Merge pull request #85 from dscho/simple-regex

Simple regex
This commit is contained in:
Joshua Warner 2013-10-21 13:30:57 -07:00
commit b20dcd268c
2 changed files with 78 additions and 9 deletions

View File

@ -35,20 +35,38 @@ public class Pattern {
private final String pattern;
protected Pattern(String pattern, int flags) {
this.pattern = pattern;
this.pattern = trivial(pattern);
this.patternFlags = flags;
if (! trivial(pattern)) {
throw new UnsupportedOperationException
("only trivial regular expressions are supported so far");
}
}
private static boolean trivial(String pattern) {
private static String trivial(String pattern) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < pattern.length(); ++i) {
char c = pattern.charAt(i);
switch (c) {
case '\\':
if (++i == pattern.length()) {
break;
}
c = pattern.charAt(i);
if (c == '0') {
int len = digits(pattern, ++i, 3, 8);
if (len == 3 && pattern.charAt(i) > '3') {
--len;
}
c = (char)Integer.parseInt(pattern.substring(i, i + len), 8);
i += len - 1;
} else if (c == 'x' || c == 'u') {
int len = digits(pattern, ++i, 4, 16);
c = (char)Integer.parseInt(pattern.substring(i, i + len), 16);
i += len - 1;
} else {
c = unescape(pattern.charAt(i));
}
if (c != -1) {
break;
}
// fallthru
case '.':
case '*':
case '+':
@ -62,10 +80,50 @@ public class Pattern {
case ')':
case '^':
case '$':
return false;
throw new UnsupportedOperationException
("only trivial regular expressions are supported so far (" + pattern + ")");
}
buffer.append(c);
}
return buffer.toString();
}
private static int digits(String s, int offset, int maxLength, int base) {
for (int i = 0; ; ++i) {
if (i == maxLength || offset + i >= s.length()) {
return i;
}
int value = s.charAt(offset + i) - '0';
if (value < 0) {
return i;
}
if (base > 10 && value >= 10) {
value += 10 - (value >= 'a' - '0' ? 'a' - '0' : 'A' - '0');
}
if (value >= base) {
return i;
}
}
return true;
}
private static char unescape(char c) {
switch (c) {
case '\\':
return c;
case 'a':
return 0x0007;
case 'e':
return 0x001B;
case 'f':
return 0x000C;
case 'n':
return 0x000A;
case 'r':
return 0x000D;
case 't':
return 0x0009;
}
return (char)-1;
}
public static Pattern compile(String regex) {

View File

@ -105,6 +105,15 @@ public class Strings {
(prematureEOS ? "\u00ae\ufffd" : "\u00ae\uaeaf"));
}
public static void testTrivialPattern() throws Exception {
expect("?7".matches("\\0777"));
expect("\007".matches("\\a"));
expect("\\".matches("\\\\"));
expect("J".matches("\\x4A"));
expect("a".matches("\\x61"));
expect("\0078".matches("\\078"));
}
public static void main(String[] args) throws Exception {
expect(new String(new byte[] { 99, 111, 109, 46, 101, 99, 111, 118, 97,
116, 101, 46, 110, 97, 116, 46, 98, 117,
@ -193,5 +202,7 @@ public class Strings {
32, 110, 117, 116, 115 },
System.getProperty("line.separator").getBytes())));
}
testTrivialPattern();
}
}