diff --git a/crates/perry-runtime/src/regex/grammar.rs b/crates/perry-runtime/src/regex/grammar.rs index 83300d52e0..633aec576e 100644 --- a/crates/perry-runtime/src/regex/grammar.rs +++ b/crates/perry-runtime/src/regex/grammar.rs @@ -90,8 +90,12 @@ fn is_regex_identity_escape(ch: char) -> bool { ) } -fn push_escaped_literal(out: &mut String, ch: char) { +fn push_escaped_literal(out: &mut String, ch: char, in_class: bool) { match ch { + '-' if in_class => { + out.push('\\'); + out.push(ch); + } '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '\\' => { out.push('\\'); out.push(ch); @@ -257,7 +261,7 @@ pub(super) fn js_regex_to_rust(pattern: &str) -> String { } } ch if is_regex_identity_escape(ch) => { - push_escaped_literal(&mut result, ch); + push_escaped_literal(&mut result, ch, in_class); i += 2; } // Pass through all other backslash sequences as-is. (An escaped diff --git a/test-parity/node-suite/globals/regexp-character-class-escaped-hyphen.ts b/test-parity/node-suite/globals/regexp-character-class-escaped-hyphen.ts new file mode 100644 index 0000000000..2d0e40fceb --- /dev/null +++ b/test-parity/node-suite/globals/regexp-character-class-escaped-hyphen.ts @@ -0,0 +1,19 @@ +const patterns = [ + "[\\-]", + "[a\\- ]", + "[a-z]", + "[:]", + "[ ]", + "[a-z ]", + "[:\\- ]", + " {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n", +]; + +for (const pattern of patterns) { + try { + const regex = new RegExp(pattern); + console.log("OK /" + pattern + "/ " + regex.test("-")); + } catch (error: any) { + console.log("FAIL /" + pattern + "/ -> " + error.message); + } +}