diff --git a/src/parse.rs b/src/parse.rs index 7a7993f..afb95ec 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -333,14 +333,14 @@ where '(' => { if self.try_consume_str("(?=") { // Positive lookahead. - quantifier_allowed = false; + quantifier_allowed = !self.flags.unicode; result.push(self.consume_lookaround_assertion(LookaroundParams { negate: false, backwards: false, })?); } else if self.try_consume_str("(?!") { // Negative lookahead. - quantifier_allowed = false; + quantifier_allowed = !self.flags.unicode; result.push(self.consume_lookaround_assertion(LookaroundParams { negate: true, backwards: false, diff --git a/tests/tests.rs b/tests/tests.rs index 0183437..32783e9 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1582,3 +1582,93 @@ fn test_high_folds_tc(tc: TestConfig) { tc.test_match_fails(r"\u{1BD}", "", "\u{1BE}"); tc.test_match_fails(r"\u{1BD}", "i", "\u{1BE}"); } + +#[test] +fn test_quantifiable_assertion_not_followed_by() { + test_with_configs(test_quantifiable_assertion_not_followed_by_tc) +} + +/// 262 test/annexB/language/literals/regexp/quantifiable-assertion-not-followed-by.js +fn test_quantifiable_assertion_not_followed_by_tc(tc: TestConfig) { + tc.compile(r#"[a-e](?!Z)*"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("a"); + tc.compile(r#"[a-e](?!Z)+"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z)?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("a"); + tc.compile(r#"[a-e](?!Z){2}"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z){2,}"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z){2,3}"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z)*?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("a"); + tc.compile(r#"[a-e](?!Z)+?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z)??"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("a"); + tc.compile(r#"[a-e](?!Z){2}?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z){2,}?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); + tc.compile(r#"[a-e](?!Z){2,3}?"#) + .match1f(r#"aZZZZ bZZZ cZZ dZ e"#) + .test_eq("e"); +} + +#[test] +fn test_quantifiable_assertion_followed_by() { + test_with_configs(test_quantifiable_assertion_followed_by_tc) +} + +/// 262 test/annexB/language/literals/regexp/quantifiable-assertion-followed-by.js +fn test_quantifiable_assertion_followed_by_tc(tc: TestConfig) { + tc.compile(r#".(?=Z)*"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("a"); + tc.compile(r#".(?=Z)+"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z)?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("a"); + tc.compile(r#".(?=Z){2}"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z){2,}"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z){2,3}"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z)*?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("a"); + tc.compile(r#".(?=Z)+?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z)??"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("a"); + tc.compile(r#".(?=Z){2}?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z){2,}?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); + tc.compile(r#".(?=Z){2,3}?"#) + .match1f(r#"a bZ cZZ dZZZ eZZZZ"#) + .test_eq("b"); +}