Skip to content

Commit

Permalink
Support lookbehind assertions in regexp
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Oct 20, 2020
1 parent d44c223 commit bf18fe8
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
4 changes: 3 additions & 1 deletion parser/regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ func (self *_RegExp_parser) scanGroup() {
switch {
case ch == '=' || ch == '!':
self.error(-1, "re2: Invalid (%s) <lookahead>", self.str[self.chrOffset:self.chrOffset+2])
case ch != ':' && ch != '<':
case ch == '<':
self.error(-1, "re2: Invalid (%s) <lookbehind>", self.str[self.chrOffset:self.chrOffset+2])
case ch != ':':
self.error(-1, "Invalid group")
self.invalid = true
}
Expand Down
11 changes: 4 additions & 7 deletions parser/regexp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func TestRegExp(t *testing.T) {
test("(?U)", "", "Invalid group")
test("(?)|(?i)", "", "Invalid group")
test("(?P<w>)(?P<w>)(?P<D>)", "", "Invalid group")

test(`<%([\s\S]+?)%>`, `<%([`+WhitespaceChars+`S]+?)%>`, "S in class")

test("(?<=y)x", "(?<=y)x", "re2: Invalid (?<) <lookbehind>")
}

{
Expand All @@ -52,11 +56,6 @@ func TestRegExp(t *testing.T) {
is(err, nil)
}

testErr := func(input string, expectErr string) {
_, err := TransformRegExp(input)
is(err, expectErr)
}

test("", "")

test("abc", "abc")
Expand Down Expand Up @@ -109,8 +108,6 @@ func TestRegExp(t *testing.T) {

test("\\04", "\\x04")

testErr(`<%([\s\S]+?)%>`, "S in class")

test(`(.)^`, "([^\\r\\n])^")

test(`\$`, `\$`)
Expand Down
13 changes: 13 additions & 0 deletions regexp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,19 @@ func TestRegexpInvalidGroup(t *testing.T) {
testScript1(TESTLIB+SCRIPT, _undefined, t)
}

func TestRegexpLookbehindAssertion(t *testing.T) {
const SCRIPT = `
var re = /(?<=Jack|Tom)Sprat/;
assert(re.test("JackSprat"), "#1");
assert(!re.test("JohnSprat"), "#2");
re = /(?<!-)\d+/;
assert(re.test("3"), "#3");
assert(!re.test("-3"), "#4");
`
testScript1(TESTLIB+SCRIPT, _undefined, t)
}

func BenchmarkRegexpSplitWithBackRef(b *testing.B) {
const SCRIPT = `
"aaaaaaaaaaaaaaaaaaaaaaaaa++bbbbbbbbbbbbbbbbbbbbbb+-ccccccccccccccccccccccc".split(/([+-])\1/)
Expand Down

0 comments on commit bf18fe8

Please sign in to comment.