diff --git a/Sources/_StringProcessing/LiteralPrinter.swift b/Sources/_StringProcessing/LiteralPrinter.swift index 0e5b448b..0b0037ec 100644 --- a/Sources/_StringProcessing/LiteralPrinter.swift +++ b/Sources/_StringProcessing/LiteralPrinter.swift @@ -389,7 +389,7 @@ extension LiteralPrinter { } func prepareQuotedLiteral(_ literal: String) -> String { - if options.usesExtendedWhitespace || literal.containsRegexMetaCharacters { + if options.usesExtendedWhitespace { return #"\Q\#(literal)\E"# } else { return literal.escapingConfusableCharacters() @@ -474,8 +474,12 @@ extension String { func escapingConfusableCharacters() -> String { reduce(into: "") { result, ch in for scalar in ch.unicodeScalars { - if scalar.isPrintableASCII { - result.append(Character(scalar)) + let ch = Character(scalar) + if ch.isRegexMetaCharacter { + result.append("\\") + result.append(ch) + } else if scalar.isPrintableASCII { + result.append(ch) } else { result.append(scalar.escapedString) } diff --git a/Tests/RegexTests/LiteralPrinterTests.swift b/Tests/RegexTests/LiteralPrinterTests.swift index 69f273fd..2b109b32 100644 --- a/Tests/RegexTests/LiteralPrinterTests.swift +++ b/Tests/RegexTests/LiteralPrinterTests.swift @@ -40,6 +40,12 @@ extension RegexTests { XCTAssertEqual("\(printableRegex)", regexString) } + func testLiteral169973074() throws { + let regexString = #"^id\-\d+"# + let regex = try Regex(regexString) + _literalTest(regex, expected: regexString) + } + func testUnicodeEscapes() throws { let regex0 = #/[a]\u0301/# _literalTest(regex0, expected: #"[a]\u0301"#)