📄 rangetoken.java
字号:
} this.ranges = new int[wp]; System.arraycopy(result, 0, this.ranges, 0, wp); // this.ranges is sorted and compacted. } /** * @param tok Ignore whether it is NRANGE or not. */ protected void intersectRanges(Token token) { RangeToken tok = (RangeToken)token; if (tok.ranges == null || this.ranges == null) return; this.icaseCache = null; this.sortRanges(); this.compactRanges(); tok.sortRanges(); tok.compactRanges(); int[] result = new int[this.ranges.length+tok.ranges.length]; int wp = 0, src1 = 0, src2 = 0; while (src1 < this.ranges.length && src2 < tok.ranges.length) { int src1begin = this.ranges[src1]; int src1end = this.ranges[src1+1]; int src2begin = tok.ranges[src2]; int src2end = tok.ranges[src2+1]; if (src1end < src2begin) { // Not overlapped // src1: o-----o // src2: o-----o // res: empty // Reuse src2 src1 += 2; } else if (src1end >= src2begin && src1begin <= src2end) { // Overlapped // src1: o--------o // src2: o----o // src2: o----o // src2: o----o // src2: o------------o if (src2begin <= src2begin && src1end <= src2end) { // src1: o--------o // src2: o------------o // res: o--------o // Reuse src2 result[wp++] = src1begin; result[wp++] = src1end; src1 += 2; } else if (src2begin <= src1begin) { // src1: o--------o // src2: o----o // res: o--o // Reuse the rest of src1 result[wp++] = src1begin; result[wp++] = src2end; this.ranges[src1] = src2end+1; src2 += 2; } else if (src1end <= src2end) { // src1: o--------o // src2: o----o // res: o--o // Reuse src2 result[wp++] = src2begin; result[wp++] = src1end; src1 += 2; } else { // src1: o--------o // src2: o----o // res: o----o // Reuse the rest of src1 result[wp++] = src2begin; result[wp++] = src2end; this.ranges[src1] = src2end+1; } } else if (src2end < src1begin) { // Not overlapped // src1: o-----o // src2: o----o src2 += 2; } else { throw new RuntimeException("Token#intersectRanges(): Internal Error: [" +this.ranges[src1] +","+this.ranges[src1+1] +"] & ["+tok.ranges[src2] +","+tok.ranges[src2+1] +"]"); } } while (src1 < this.ranges.length) { result[wp++] = this.ranges[src1++]; result[wp++] = this.ranges[src1++]; } this.ranges = new int[wp]; System.arraycopy(result, 0, this.ranges, 0, wp); // this.ranges is sorted and compacted. } /** * for RANGE: Creates complement. * for NRANGE: Creates the same meaning RANGE. */ static Token complementRanges(Token token) { if (token.type != RANGE && token.type != NRANGE) throw new IllegalArgumentException("Token#complementRanges(): must be RANGE: "+token.type); RangeToken tok = (RangeToken)token; tok.sortRanges(); tok.compactRanges(); int len = tok.ranges.length+2; if (tok.ranges[0] == 0) len -= 2; int last = tok.ranges[tok.ranges.length-1]; if (last == UTF16_MAX) len -= 2; RangeToken ret = Token.createRange(); ret.ranges = new int[len]; int wp = 0; if (tok.ranges[0] > 0) { ret.ranges[wp++] = 0; ret.ranges[wp++] = tok.ranges[0]-1; } for (int i = 1; i < tok.ranges.length-2; i += 2) { ret.ranges[wp++] = tok.ranges[i]+1; ret.ranges[wp++] = tok.ranges[i+1]-1; } if (last != UTF16_MAX) { ret.ranges[wp++] = last+1; ret.ranges[wp] = UTF16_MAX; } ret.setCompacted(); return ret; } synchronized RangeToken getCaseInsensitiveToken() { if (this.icaseCache != null) return this.icaseCache; RangeToken uppers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange(); for (int i = 0; i < this.ranges.length; i += 2) { for (int ch = this.ranges[i]; ch <= this.ranges[i+1]; ch ++) { if (ch > 0xffff) uppers.addRange(ch, ch); else { char uch = Character.toUpperCase((char)ch); uppers.addRange(uch, uch); } } } RangeToken lowers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange(); for (int i = 0; i < uppers.ranges.length; i += 2) { for (int ch = uppers.ranges[i]; ch <= uppers.ranges[i+1]; ch ++) { if (ch > 0xffff) lowers.addRange(ch, ch); else { char uch = Character.toUpperCase((char)ch); lowers.addRange(uch, uch); } } } lowers.mergeRanges(uppers); lowers.mergeRanges(this); lowers.compactRanges(); this.icaseCache = lowers; return lowers; } void dumpRanges() { System.err.print("RANGE: "); if (this.ranges == null) System.err.println(" NULL"); for (int i = 0; i < this.ranges.length; i += 2) { System.err.print("["+this.ranges[i]+","+this.ranges[i+1]+"] "); } System.err.println(""); } boolean match(int ch) { if (this.map == null) this.createMap(); boolean ret; if (this.type == RANGE) { if (ch < MAPSIZE) return (this.map[ch/32] & (1<<(ch&0x1f))) != 0; ret = false; for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) { if (this.ranges[i] <= ch && ch <= this.ranges[i+1]) return true; } } else { if (ch < MAPSIZE) return (this.map[ch/32] & (1<<(ch&0x1f))) == 0; ret = true; for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) { if (this.ranges[i] <= ch && ch <= this.ranges[i+1]) return false; } } return ret; } private static final int MAPSIZE = 256; private void createMap() { int asize = MAPSIZE/32; // 32 is the number of bits in `int'. int [] map = new int[asize]; int nonMapIndex = this.ranges.length; for (int i = 0; i < asize; ++i) { map[i] = 0; } for (int i = 0; i < this.ranges.length; i += 2) { int s = this.ranges[i]; int e = this.ranges[i+1]; if (s < MAPSIZE) { for (int j = s; j <= e && j < MAPSIZE; j++) { map[j/32] |= 1<<(j&0x1f); // s&0x1f : 0-31 } } else { nonMapIndex = i; break; } if (e >= MAPSIZE) { nonMapIndex = i; break; } } this.map = map; this.nonMapIndex = nonMapIndex; //for (int i = 0; i < asize; i ++) System.err.println("Map: "+Integer.toString(this.map[i], 16)); } public String toString(int options) { String ret; if (this.type == RANGE) { if (this == Token.token_dot) ret = "."; else if (this == Token.token_0to9) ret = "\\d"; else if (this == Token.token_wordchars) ret = "\\w"; else if (this == Token.token_spaces) ret = "\\s"; else { StringBuffer sb = new StringBuffer(); sb.append("["); for (int i = 0; i < this.ranges.length; i += 2) { if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) sb.append(","); if (this.ranges[i] == this.ranges[i+1]) { sb.append(escapeCharInCharClass(this.ranges[i])); } else { sb.append(escapeCharInCharClass(this.ranges[i])); sb.append((char)'-'); sb.append(escapeCharInCharClass(this.ranges[i+1])); } } sb.append("]"); ret = sb.toString(); } } else { if (this == Token.token_not_0to9) ret = "\\D"; else if (this == Token.token_not_wordchars) ret = "\\W"; else if (this == Token.token_not_spaces) ret = "\\S"; else { StringBuffer sb = new StringBuffer(); sb.append("[^"); for (int i = 0; i < this.ranges.length; i += 2) { if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) sb.append(","); if (this.ranges[i] == this.ranges[i+1]) { sb.append(escapeCharInCharClass(this.ranges[i])); } else { sb.append(escapeCharInCharClass(this.ranges[i])); sb.append('-'); sb.append(escapeCharInCharClass(this.ranges[i+1])); } } sb.append("]"); ret = sb.toString(); } } return ret; } private static String escapeCharInCharClass(int ch) { String ret; switch (ch) { case '[': case ']': case '-': case '^': case ',': case '\\': ret = "\\"+(char)ch; break; case '\f': ret = "\\f"; break; case '\n': ret = "\\n"; break; case '\r': ret = "\\r"; break; case '\t': ret = "\\t"; break; case 0x1b: ret = "\\e"; break; //case 0x0b: ret = "\\v"; break; default: if (ch < 0x20) { String pre = "0"+Integer.toHexString(ch); ret = "\\x"+pre.substring(pre.length()-2, pre.length()); } else if (ch >= 0x10000) { String pre = "0"+Integer.toHexString(ch); ret = "\\v"+pre.substring(pre.length()-6, pre.length()); } else ret = ""+(char)ch; } return ret; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -