1 package com.sun.org.apache.regexp.internal; 2 3 59 60 import java.util.Vector ; 61 62 352 public class RE 353 { 354 357 public static final int MATCH_NORMAL = 0x0000; 358 359 362 public static final int MATCH_CASEINDEPENDENT = 0x0001; 363 364 367 public static final int MATCH_MULTILINE = 0x0002; 368 369 372 public static final int MATCH_SINGLELINE = 0x0004; 373 374 385 386 static final char OP_END = 'E'; static final char OP_BOL = '^'; static final char OP_EOL = '$'; static final char OP_ANY = '.'; static final char OP_ANYOF = '['; static final char OP_BRANCH = '|'; static final char OP_ATOM = 'A'; static final char OP_STAR = '*'; static final char OP_PLUS = '+'; static final char OP_MAYBE = '?'; static final char OP_ESCAPE = '\\'; static final char OP_OPEN = '('; static final char OP_CLOSE = ')'; static final char OP_BACKREF = '#'; static final char OP_GOTO = 'G'; static final char OP_NOTHING = 'N'; static final char OP_RELUCTANTSTAR = '8'; static final char OP_RELUCTANTPLUS = '='; static final char OP_RELUCTANTMAYBE = '/'; static final char OP_POSIXCLASS = 'P'; 409 static final char E_ALNUM = 'w'; static final char E_NALNUM = 'W'; static final char E_BOUND = 'b'; static final char E_NBOUND = 'B'; static final char E_SPACE = 's'; static final char E_NSPACE = 'S'; static final char E_DIGIT = 'd'; static final char E_NDIGIT = 'D'; 419 static final char POSIX_CLASS_ALNUM = 'w'; static final char POSIX_CLASS_ALPHA = 'a'; static final char POSIX_CLASS_BLANK = 'b'; static final char POSIX_CLASS_CNTRL = 'c'; static final char POSIX_CLASS_DIGIT = 'd'; static final char POSIX_CLASS_GRAPH = 'g'; static final char POSIX_CLASS_LOWER = 'l'; static final char POSIX_CLASS_PRINT = 'p'; static final char POSIX_CLASS_PUNCT = '!'; static final char POSIX_CLASS_SPACE = 's'; static final char POSIX_CLASS_UPPER = 'u'; static final char POSIX_CLASS_XDIGIT = 'x'; static final char POSIX_CLASS_JSTART = 'j'; static final char POSIX_CLASS_JPART = 'k'; 435 static final int maxNode = 65536; static final int maxParen = 16; 439 static final int offsetOpcode = 0; static final int offsetOpdata = 1; static final int offsetNext = 2; static final int nodeSize = 3; 445 446 static final String NEWLINE = System.getProperty("line.separator"); 447 448 REProgram program; CharacterIterator search; int idx; int matchFlags; 454 int parenCount; int start0; int end0; int start1; int end1; int start2; int end2; int[] startn; int[] endn; 465 int[] startBackref; int[] endBackref; 469 478 public RE(String pattern) throws RESyntaxException 479 { 480 this(pattern, MATCH_NORMAL); 481 } 482 483 493 public RE(String pattern, int matchFlags) throws RESyntaxException 494 { 495 this(new RECompiler().compile(pattern)); 496 setMatchFlags(matchFlags); 497 } 498 499 518 public RE(REProgram program, int matchFlags) 519 { 520 setProgram(program); 521 setMatchFlags(matchFlags); 522 } 523 524 531 public RE(REProgram program) 532 { 533 this(program, MATCH_NORMAL); 534 } 535 536 540 public RE() 541 { 542 this((REProgram)null, MATCH_NORMAL); 543 } 544 545 550 public static String simplePatternToFullRegularExpression(String pattern) 551 { 552 StringBuffer buf = new StringBuffer (); 553 for (int i = 0; i < pattern.length(); i++) 554 { 555 char c = pattern.charAt(i); 556 switch (c) 557 { 558 case '*': 559 buf.append(".*"); 560 break; 561 562 case '.': 563 case '[': 564 case ']': 565 case '\\': 566 case '+': 567 case '?': 568 case '{': 569 case '}': 570 case '$': 571 case '^': 572 case '|': 573 case '(': 574 case ')': 575 buf.append('\\'); 576 default: 577 buf.append(c); 578 break; 579 } 580 } 581 return buf.toString(); 582 } 583 584 597 public void setMatchFlags(int matchFlags) 598 { 599 this.matchFlags = matchFlags; 600 } 601 602 617 public int getMatchFlags() 618 { 619 return matchFlags; 620 } 621 622 629 public void setProgram(REProgram program) 630 { 631 this.program = program; 632 } 633 634 639 public REProgram getProgram() 640 { 641 return program; 642 } 643 644 648 public int getParenCount() 649 { 650 return parenCount; 651 } 652 653 658 public String getParen(int which) 659 { 660 int start; 661 if (which < parenCount && (start = getParenStart(which)) >= 0) 662 { 663 return search.substring(start, getParenEnd(which)); 664 } 665 return null; 666 } 667 668 673 public final int getParenStart(int which) 674 { 675 if (which < parenCount) 676 { 677 switch (which) 678 { 679 case 0: 680 return start0; 681 682 case 1: 683 return start1; 684 685 case 2: 686 return start2; 687 688 default: 689 if (startn == null) 690 { 691 allocParens(); 692 } 693 return startn[which]; 694 } 695 } 696 return -1; 697 } 698 699 704 public final int getParenEnd(int which) 705 { 706 if (which < parenCount) 707 { 708 switch (which) 709 { 710 case 0: 711 return end0; 712 713 case 1: 714 return end1; 715 716 case 2: 717 return end2; 718 719 default: 720 if (endn == null) 721 { 722 allocParens(); 723 } 724 return endn[which]; 725 } 726 } 727 return -1; 728 } 729 730 735 public final int getParenLength(int which) 736 { 737 if (which < parenCount) 738 { 739 return getParenEnd(which) - getParenStart(which); 740 } 741 return -1; 742 } 743 744 749 protected final void setParenStart(int which, int i) 750 { 751 if (which < parenCount) 752 { 753 switch (which) 754 { 755 case 0: 756 start0 = i; 757 break; 758 759 case 1: 760 start1 = i; 761 break; 762 763 case 2: 764 start2 = i; 765 break; 766 767 default: 768 if (startn == null) 769 { 770 allocParens(); 771 } 772 startn[which] = i; 773 break; 774 } 775 } 776 } 777 778 783 protected final void setParenEnd(int which, int i) 784 { 785 if (which < parenCount) 786 { 787 switch (which) 788 { 789 case 0: 790 end0 = i; 791 break; 792 793 case 1: 794 end1 = i; 795 break; 796 797 case 2: 798 end2 = i; 799 break; 800 801 default: 802 if (endn == null) 803 { 804 allocParens(); 805 } 806 endn[which] = i; 807 break; 808 } 809 } 810 } 811 812 818 protected void internalError(String s) throws Error 819 { 820 throw new Error ("RE internal error: " + s); 821 } 822 823 826 private final void allocParens() 827 { 828 startn = new int[maxParen]; 830 endn = new int[maxParen]; 831 832 for (int i = 0; i < maxParen; i++) 834 { 835 startn[i] = -1; 836 endn[i] = -1; 837 } 838 } 839 840 848 protected int matchNodes(int firstNode, int lastNode, int idxStart) 849 { 850 int idx = idxStart; 852 853 int next, opcode, opdata; 855 int idxNew; 856 char[] instruction = program.instruction; 857 for (int node = firstNode; node < lastNode; ) 858 { 859 opcode = instruction[node + offsetOpcode]; 860 next = node + (short)instruction[node + offsetNext]; 861 opdata = instruction[node + offsetOpdata]; 862 863 switch (opcode) 864 { 865 case OP_RELUCTANTMAYBE: 866 { 867 int once = 0; 868 do 869 { 870 if ((idxNew = matchNodes(next, maxNode, idx)) != -1) 872 { 873 return idxNew; 874 } 875 } 876 while ((once++ == 0) && (idx = matchNodes(node + nodeSize, next, idx)) != -1); 877 return -1; 878 } 879 880 case OP_RELUCTANTPLUS: 881 while ((idx = matchNodes(node + nodeSize, next, idx)) != -1) 882 { 883 if ((idxNew = matchNodes(next, maxNode, idx)) != -1) 885 { 886 return idxNew; 887 } 888 } 889 return -1; 890 891 case OP_RELUCTANTSTAR: 892 do 893 { 894 if ((idxNew = matchNodes(next, maxNode, idx)) != -1) 896 { 897 return idxNew; 898 } 899 } 900 while ((idx = matchNodes(node + nodeSize, next, idx)) != -1); 901 return -1; 902 903 case OP_OPEN: 904 905 if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) 907 { 908 startBackref[opdata] = idx; 909 } 910 if ((idxNew = matchNodes(next, maxNode, idx)) != -1) 911 { 912 if ((opdata + 1) > parenCount) 914 { 915 parenCount = opdata + 1; 916 } 917 918 if (getParenStart(opdata) == -1) 920 { 921 setParenStart(opdata, idx); 922 } 923 } 924 return idxNew; 925 926 case OP_CLOSE: 927 928 if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) 930 { 931 endBackref[opdata] = idx; 932 } 933 if ((idxNew = matchNodes(next, maxNode, idx)) != -1) 934 { 935 if ((opdata + 1) > parenCount) 937 { 938 parenCount = opdata + 1; 939 } 940 941 if (getParenEnd(opdata) == -1) 943 { 944 setParenEnd(opdata, idx); 945 } 946 } 947 return idxNew; 948 949 case OP_BACKREF: 950 { 951 int s = startBackref[opdata]; 953 int e = endBackref[opdata]; 954 955 if (s == -1 || e == -1) 957 { 958 return -1; 959 } 960 961 if (s == e) 963 { 964 break; 965 } 966 967 int l = e - s; 969 970 if (search.isEnd(idx + l - 1)) 972 { 973 return -1; 974 } 975 976 if ((matchFlags & MATCH_CASEINDEPENDENT) != 0) 978 { 979 for (int i = 0; i < l; i++) 981 { 982 if (Character.toLowerCase(search.charAt(idx++)) != Character.toLowerCase(search.charAt(s + i))) 983 { 984 return -1; 985 } 986 } 987 } 988 else 989 { 990 for (int i = 0; i < l; i++) 992 { 993 if (search.charAt(idx++) != search.charAt(s + i)) 994 { 995 return -1; 996 } 997 } 998 } 999 } 1000 break; 1001 1002 case OP_BOL: 1003 1004 if (idx != 0) 1006 { 1007 if ((matchFlags & MATCH_MULTILINE) == MATCH_MULTILINE) 1009 { 1010 if (idx <= 0 || !isNewline(idx - 1)) { 1012 return -1; 1013 } else { 1014 break; 1015 } 1016 } 1017 return -1; 1018 } 1019 break; 1020 1021 case OP_EOL: 1022 1023 if (!search.isEnd(0) && !search.isEnd(idx)) 1025 { 1026 if ((matchFlags & MATCH_MULTILINE) == MATCH_MULTILINE) 1028 { 1029 if (! isNewline(idx)) { 1031 return -1; 1032 } else { 1033 break; 1034 } 1035 } 1036 return -1; 1037 } 1038 break; 1039 1040 case OP_ESCAPE: 1041 1042 switch (opdata) 1044 { 1045 case E_NBOUND: 1047 case E_BOUND: 1048 { 1049 char cLast = ((idx == getParenStart(0)) ? '\n' : search.charAt(idx - 1)); 1050 char cNext = ((search.isEnd(idx)) ? '\n' : search.charAt(idx)); 1051 if ((Character.isLetterOrDigit(cLast) == Character.isLetterOrDigit(cNext)) == (opdata == E_BOUND)) 1052 { 1053 return -1; 1054 } 1055 } 1056 break; 1057 1058 case E_ALNUM: 1060 case E_NALNUM: 1061 case E_DIGIT: 1062 case E_NDIGIT: 1063 case E_SPACE: 1064 case E_NSPACE: 1065 1066 if (search.isEnd(idx)) 1068 { 1069 return -1; 1070 } 1071 1072 switch (opdata) 1074 { 1075 case E_ALNUM: 1076 case E_NALNUM: 1077 if (!(Character.isLetterOrDigit(search.charAt(idx)) == (opdata == E_ALNUM))) 1078 { 1079 return -1; 1080 } 1081 break; 1082 1083 case E_DIGIT: 1084 case E_NDIGIT: 1085 if (!(Character.isDigit(search.charAt(idx)) == (opdata == E_DIGIT))) 1086 { 1087 return -1; 1088 } 1089 break; 1090 1091 case E_SPACE: 1092 case E_NSPACE: 1093 if (!(Character.isWhitespace(search.charAt(idx)) == (opdata == E_SPACE))) 1094 { 1095 return -1; 1096 } 1097 break; 1098 } 1099 idx++; 1100 break; 1101 1102 default: 1103 internalError("Unrecognized escape '" + opdata + "'"); 1104 } 1105 break; 1106 1107 case OP_ANY: 1108 1109 if((matchFlags & MATCH_SINGLELINE) == MATCH_SINGLELINE) { 1110 if(search.isEnd(idx)) 1112 { 1113 return -1; 1114 } 1115 idx++; 1116 break; 1117 } 1118 else 1119 { 1120 if (search.isEnd(idx) || search.charAt(idx++) == '\n') 1122 { 1123 return -1; 1124 } 1125 break; 1126 } 1127 1128 case OP_ATOM: 1129 { 1130 if (search.isEnd(idx)) 1132 { 1133 return -1; 1134 } 1135 1136 int lenAtom = opdata; 1138 int startAtom = node + nodeSize; 1139 1140 if (search.isEnd(lenAtom + idx - 1)) 1142 { 1143 return -1; 1144 } 1145 1146 if ((matchFlags & MATCH_CASEINDEPENDENT) != 0) 1148 { 1149 for (int i = 0; i < lenAtom; i++) 1150 { 1151 if (Character.toLowerCase(search.charAt(idx++)) != Character.toLowerCase(instruction[startAtom + i])) 1152 { 1153 return -1; 1154 } 1155 } 1156 } 1157 else 1158 { 1159 for (int i = 0; i < lenAtom; i++) 1160 { 1161 if (search.charAt(idx++) != instruction[startAtom + i]) 1162 { 1163 return -1; 1164 } 1165 } 1166 } 1167 } 1168 break; 1169 1170 case OP_POSIXCLASS: 1171 { 1172 if (search.isEnd(idx)) 1174 { 1175 return -1; 1176 } 1177 1178 switch (opdata) 1179 { 1180 case POSIX_CLASS_ALNUM: 1181 if (!Character.isLetterOrDigit(search.charAt(idx))) 1182 { 1183 return -1; 1184 } 1185 break; 1186 1187 case POSIX_CLASS_ALPHA: 1188 if (!Character.isLetter(search.charAt(idx))) 1189 { 1190 return -1; 1191 } 1192 break; 1193 1194 case POSIX_CLASS_DIGIT: 1195 if (!Character.isDigit(search.charAt(idx))) 1196 { 1197 return -1; 1198 } 1199 break; 1200 1201 case POSIX_CLASS_BLANK: if (!Character.isSpaceChar(search.charAt(idx))) 1203 { 1204 return -1; 1205 } 1206 break; 1207 1208 case POSIX_CLASS_SPACE: 1209 if (!Character.isWhitespace(search.charAt(idx))) 1210 { 1211 return -1; 1212 } 1213 break; 1214 1215 case POSIX_CLASS_CNTRL: 1216 if (Character.getType(search.charAt(idx)) != Character.CONTROL) 1217 { 1218 return -1; 1219 } 1220 break; 1221 1222 case POSIX_CLASS_GRAPH: switch (Character.getType(search.charAt(idx))) 1224 { 1225 case Character.MATH_SYMBOL: 1226 case Character.CURRENCY_SYMBOL: 1227 case Character.MODIFIER_SYMBOL: 1228 case Character.OTHER_SYMBOL: 1229 break; 1230 1231 default: 1232 return -1; 1233 } 1234 break; 1235 1236 case POSIX_CLASS_LOWER: 1237 if (Character.getType(search.charAt(idx)) != Character.LOWERCASE_LETTER) 1238 { 1239 return -1; 1240 } 1241 break; 1242 1243 case POSIX_CLASS_UPPER: 1244 if (Character.getType(search.charAt(idx)) != Character.UPPERCASE_LETTER) 1245 { 1246 return -1; 1247 } 1248 break; 1249 1250 case POSIX_CLASS_PRINT: 1251 if (Character.getType(search.charAt(idx)) == Character.CONTROL) 1252 { 1253 return -1; 1254 } 1255 break; 1256 1257 case POSIX_CLASS_PUNCT: 1258 { 1259 int type = Character.getType(search.charAt(idx)); 1260 switch(type) 1261 { 1262 case Character.DASH_PUNCTUATION: 1263 case Character.START_PUNCTUATION: 1264 case Character.END_PUNCTUATION: 1265 case Character.CONNECTOR_PUNCTUATION: 1266 case Character.OTHER_PUNCTUATION: 1267 break; 1268 1269 default: 1270 return -1; 1271 } 1272 } 1273 break; 1274 1275 case POSIX_CLASS_XDIGIT: { 1277 boolean isXDigit = ((search.charAt(idx) >= '0' && search.charAt(idx) <= '9') || 1278 (search.charAt(idx) >= 'a' && search.charAt(idx) <= 'f') || 1279 (search.charAt(idx) >= 'A' && search.charAt(idx) <= 'F')); 1280 if (!isXDigit) 1281 { 1282 return -1; 1283 } 1284 } 1285 break; 1286 1287 case POSIX_CLASS_JSTART: 1288 if (!Character.isJavaIdentifierStart(search.charAt(idx))) 1289 { 1290 return -1; 1291 } 1292 break; 1293 1294 case POSIX_CLASS_JPART: 1295 if (!Character.isJavaIdentifierPart(search.charAt(idx))) 1296 { 1297 return -1; 1298 } 1299 break; 1300 1301 default: 1302 internalError("Bad posix class"); 1303 break; 1304 } 1305 1306 idx++; 1308 } 1309 break; 1310 1311 case OP_ANYOF: 1312 { 1313 if (search.isEnd(idx)) 1315 { 1316 return -1; 1317 } 1318 1319 char c = search.charAt(idx); 1321 boolean caseFold = (matchFlags & MATCH_CASEINDEPENDENT) != 0; 1322 if (caseFold) 1323 { 1324 c = Character.toLowerCase(c); 1325 } 1326 1327 int idxRange = node + nodeSize; 1329 int idxEnd = idxRange + (opdata * 2); 1330 boolean match = false; 1331 for (int i = idxRange; i < idxEnd; ) 1332 { 1333 char s = instruction[i++]; 1335 char e = instruction[i++]; 1336 1337 if (caseFold) 1339 { 1340 s = Character.toLowerCase(s); 1341 e = Character.toLowerCase(e); 1342 } 1343 1344 if (c >= s && c <= e) 1346 { 1347 match = true; 1348 break; 1349 } 1350 } 1351 1352 if (!match) 1354 { 1355 return -1; 1356 } 1357 idx++; 1358 } 1359 break; 1360 1361 case OP_BRANCH: 1362 { 1363 if (instruction[next + offsetOpcode] != OP_BRANCH) 1365 { 1366 node += nodeSize; 1368 continue; 1369 } 1370 1371 short nextBranch; 1373 do 1374 { 1375 if ((idxNew = matchNodes(node + nodeSize, maxNode, idx)) != -1) 1377 { 1378 return idxNew; 1379 } 1380 1381 nextBranch = (short)instruction[node + offsetNext]; 1383 node += nextBranch; 1384 } 1385 while (nextBranch != 0 && (instruction[node + offsetOpcode] == OP_BRANCH)); 1386 1387 return -1; 1389 } 1390 1391 case OP_NOTHING: 1392 case OP_GOTO: 1393 1394 break; 1396 1397 case OP_END: 1398 1399 setParenEnd(0, idx); 1401 return idx; 1402 1403 default: 1404 1405 internalError("Invalid opcode '" + opcode + "'"); 1407 } 1408 1409 node = next; 1411 } 1412 1413 internalError("Corrupt program"); 1415 return -1; 1416 } 1417 1418 1425 protected boolean matchAt(int i) 1426 { 1427 start0 = -1; 1429 end0 = -1; 1430 start1 = -1; 1431 end1 = -1; 1432 start2 = -1; 1433 end2 = -1; 1434 startn = null; 1435 endn = null; 1436 parenCount = 1; 1437 setParenStart(0, i); 1438 1439 if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) 1441 { 1442 startBackref = new int[maxParen]; 1443 endBackref = new int[maxParen]; 1444 } 1445 1446 int idx; 1448 if ((idx = matchNodes(0, maxNode, i)) != -1) 1449 { 1450 setParenEnd(0, idx); 1451 return true; 1452 } 1453 1454 parenCount = 0; 1456 return false; 1457 } 1458 1459 1466 public boolean match(String search, int i) 1467 { 1468 return match(new StringCharacterIterator(search), i); 1469 } 1470 1471 1478 public boolean match(CharacterIterator search, int i) 1479 { 1480 if (program == null) 1482 { 1483 internalError("No RE program to run!"); 1486 } 1487 1488 this.search = search; 1490 1491 if (program.prefix == null) 1493 { 1494 for ( ;! search.isEnd(i - 1); i++) 1496 { 1497 if (matchAt(i)) 1499 { 1500 return true; 1501 } 1502 } 1503 return false; 1504 } 1505 else 1506 { 1507 boolean caseIndependent = (matchFlags & MATCH_CASEINDEPENDENT) != 0; 1509 char[] prefix = program.prefix; 1510 for ( ;! search.isEnd(i + prefix.length - 1); i++) 1511 { 1512 boolean match = false; 1514 if (caseIndependent) 1515 match = Character.toLowerCase(search.charAt(i)) == Character.toLowerCase(prefix[0]); 1516 else 1517 match = search.charAt(i) == prefix[0]; 1518 if (match) 1519 { 1520 int firstChar = i++; 1522 int k; 1523 for (k = 1; k < prefix.length; ) 1524 { 1525 if (caseIndependent) 1527 match = Character.toLowerCase(search.charAt(i++)) == Character.toLowerCase(prefix[k++]); 1528 else 1529 match = search.charAt(i++) == prefix[k++]; 1530 if (!match) 1531 { 1532 break; 1533 } 1534 } 1535 1536 if (k == prefix.length) 1538 { 1539 if (matchAt(firstChar)) 1541 { 1542 return true; 1543 } 1544 } 1545 1546 i = firstChar; 1548 } 1549 } 1550 return false; 1551 } 1552 } 1553 1554 1559 public boolean match(String search) 1560 { 1561 return match(search, 0); 1562 } 1563 1564 1573 public String [] split(String s) 1574 { 1575 Vector v = new Vector (); 1577 1578 int pos = 0; 1580 int len = s.length(); 1581 1582 while (pos < len && match(s, pos)) 1584 { 1585 int start = getParenStart(0); 1587 1588 int newpos = getParenEnd(0); 1590 1591 if (newpos == pos) 1593 { 1594 v.addElement(s.substring(pos, start + 1)); 1595 newpos++; 1596 } 1597 else 1598 { 1599 v.addElement(s.substring(pos, start)); 1600 } 1601 1602 pos = newpos; 1604 } 1605 1606 String remainder = s.substring(pos); 1608 if (remainder.length() != 0) 1609 { 1610 v.addElement(remainder); 1611 } 1612 1613 String [] ret = new String [v.size()]; 1615 v.copyInto(ret); 1616 return ret; 1617 } 1618 1619 1623 public static final int REPLACE_ALL = 0x0000; 1624 1625 1629 public static final int REPLACE_FIRSTONLY = 0x0001; 1630 1631 1644 public String subst(String substituteIn, String substitution) 1645 { 1646 return subst(substituteIn, substitution, REPLACE_ALL); 1647 } 1648 1649 1666 public String subst(String substituteIn, String substitution, int flags) 1667 { 1668 StringBuffer ret = new StringBuffer (); 1670 1671 int pos = 0; 1673 int len = substituteIn.length(); 1674 1675 while (pos < len && match(substituteIn, pos)) 1677 { 1678 ret.append(substituteIn.substring(pos, getParenStart(0))); 1680 1681 ret.append(substitution); 1683 1684 int newpos = getParenEnd(0); 1686 1687 if (newpos == pos) 1689 { 1690 newpos++; 1691 } 1692 1693 pos = newpos; 1695 1696 if ((flags & REPLACE_FIRSTONLY) != 0) 1698 { 1699 break; 1700 } 1701 } 1702 1703 if (pos < len) 1705 { 1706 ret.append(substituteIn.substring(pos)); 1707 } 1708 1709 return ret.toString(); 1711 } 1712 1713 1721 public String [] grep(Object [] search) 1722 { 1723 Vector v = new Vector (); 1725 1726 for (int i = 0; i < search.length; i++) 1728 { 1729 String s = search[i].toString(); 1731 1732 if (match(s)) 1734 { 1735 v.addElement(s); 1736 } 1737 } 1738 1739 String [] ret = new String [v.size()]; 1741 v.copyInto(ret); 1742 return ret; 1743 } 1744 1745 1746 private boolean isNewline(int i) { 1747 1748 if (i < NEWLINE.length() - 1) { 1749 return false; 1750 } 1751 1752 if (search.charAt(i) == '\n') { 1753 return true; 1754 } 1755 1756 for (int j = NEWLINE.length() - 1; j >= 0; j--, i--) { 1757 if (NEWLINE.charAt(j) != search.charAt(i)) { 1758 return false; 1759 } 1760 } 1761 return true; 1762 } 1763} 1764 | Popular Tags |