Regex: implement negative look-arounds

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin 2013-11-20 09:57:04 -06:00
parent 8b611c8075
commit 098f688cd8
4 changed files with 23 additions and 4 deletions

View File

@ -61,5 +61,6 @@ public class Regex {
expectGroups("a|(b|c)", "c", "c");
expectGroups("(?=a)a", "a");
expectGroups(".*(o)(?<=[A-Z][a-z]*)", "Hello", "o");
expectNoMatch("(?!a).", "a");
}
}

View File

@ -228,10 +228,11 @@ class Compiler implements PikeVMOpcodes {
private class Lookaround extends Expression {
private final Group group = new Group(false, null);
private final boolean forward;
private final boolean forward, negative;
public Lookaround(boolean forward) {
public Lookaround(boolean forward, boolean negative) {
this.forward = forward;
this.negative = negative;
}
@Override
@ -240,7 +241,9 @@ class Compiler implements PikeVMOpcodes {
if (!forward) {
vm.reverse();
}
output.add(forward ? LOOKAHEAD : LOOKBEHIND);
output.add(forward ?
(negative ? NEGATIVE_LOOKAHEAD : LOOKAHEAD) :
(negative ? NEGATIVE_LOOKAHEAD : LOOKBEHIND));
output.add(output.addLookaround(vm));
}
}
@ -327,9 +330,10 @@ class Compiler implements PikeVMOpcodes {
case ':':
capturing = false;
break;
case '!':
case '=': {
capturing = false;
Lookaround lookaround = new Lookaround(lookAhead);
Lookaround lookaround = new Lookaround(lookAhead, c == '!');
current.push(lookaround);
groups.push(lookaround.group);
continue;

View File

@ -358,6 +358,18 @@ class PikeVM implements PikeVMOpcodes {
current.queueImmediately(pc, pc + 2, false);
}
break;
case NEGATIVE_LOOKAHEAD:
if (!lookarounds[program[pc + 1]].matches(characters,
i, characters.length, true, false, null)) {
current.queueImmediately(pc, pc + 2, false);
}
break;
case NEGATIVE_LOOKBEHIND:
if (!lookarounds[program[pc + 1]].matches(characters,
i - 1, -1, true, false, null)) {
current.queueImmediately(pc, pc + 2, false);
}
break;
/* immediate opcodes, i.e. thread continues within the same step */
case SAVE_OFFSET:
if (result != null) {

View File

@ -26,6 +26,8 @@ interface PikeVMOpcodes {
final static int LOOKAHEAD = -30;
final static int LOOKBEHIND = -31;
final static int NEGATIVE_LOOKAHEAD = -32;
final static int NEGATIVE_LOOKBEHIND = -33;
final static int SAVE_OFFSET = -40;