Skip to content

Commit 49d62af

Browse files
natecook1000hamishknight
authored andcommitted
Fix lookaheads with quantifiers
On success, the subpatterns in lookaheads like (?=.*e) had a save point that persisted, causing the logic in the lookahead group to be invalid.
1 parent 7af91d6 commit 49d62af

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

Sources/_StringProcessing/ByteCodeGen.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ fileprivate extension Compiler.ByteCodeGen {
306306
save(restoringAt: success)
307307
save(restoringAt: intercept)
308308
<sub-pattern> // failure restores at intercept
309-
clearSavePoint // remove intercept
309+
clearThrough(intercept) // remove intercept and any leftovers from <sub-pattern>
310310
<if negative>:
311311
clearSavePoint // remove success
312312
fail // positive->success, negative propagates
@@ -324,7 +324,7 @@ fileprivate extension Compiler.ByteCodeGen {
324324
builder.buildSave(success)
325325
builder.buildSave(intercept)
326326
try emitNode(child)
327-
builder.buildClear()
327+
builder.buildClearThrough(intercept)
328328
if !positive {
329329
builder.buildClear()
330330
}

Tests/RegexTests/MatchTests.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,7 @@ extension RegexTests {
891891
input: "Price: 100 dollars", match: nil)
892892
firstMatchTest(
893893
#"(?=\d+ dollars)\d+"#,
894-
input: "Price: 100 dollars", match: "100",
895-
xfail: true) // TODO
894+
input: "Price: 100 dollars", match: "100")
896895

897896
firstMatchTest(
898897
#"\d+(*pla: dollars)"#,
@@ -917,6 +916,14 @@ extension RegexTests {
917916
#"\d+(*negative_lookahead: dollars)"#,
918917
input: "Price: 100 pesos", match: "100")
919918

919+
// More complex lookaheads
920+
firstMatchTest(
921+
#"(?=.*e)(?=.*o)(?!.*z)"#,
922+
input: "hello", match: "")
923+
firstMatchTest(
924+
#"^(?=.*e)(?=.*o)(?!.*h)"#,
925+
input: "hello", match: nil)
926+
920927
firstMatchTest(
921928
#"(?<=USD)\d+"#, input: "Price: USD100", match: "100", xfail: true)
922929
firstMatchTest(

0 commit comments

Comments
 (0)