Regex: compiler vs. REPL

This compiles and works as expected:

func classNameFromReflection(_ reflection: String) -> String {

  let regex = /(\w+Play)\(/
  let name = reflection.firstMatch(of: regex)?.output.1
  return String(name ?? "classNameFromReflection: ERROR")

}

This, however, confuses the REPL:

16:47 $ swift repl
Welcome to Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2).
Type :help for assistance.
  1> let regex = /(\w+Play)\(/
  2.

Is this a known problem, or ought I file an issue?

Try this:

% swift repl -enable-bare-slash-regex
Welcome to Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2).
Type :help for assistance.
  1> let regex = /.*/
regex: _StringProcessing.Regex<Substring> = {
…
}
  2>  

I’m using the command-line tools from Xcode 16.0.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

3 Likes

Didn't help:

12:06 $ swift repl -enable-bare-slash-regex
Welcome to Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2).
Type :help for assistance.
  1> let regex = /(\w+Play)\(/
  2.

I also tried it without the backslash in front of the open paren, no good.

This works fine, so the problem isn't primarily the backslashes, but something in the line reader which doesn't use the same parsing rules as the compiler.

12:22 $ swift repl -enable-bare-slash-regex
Welcome to Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2).
Type :help for assistance.
  1> let regex = /.*/
regex: _StringProcessing.Regex<Substring> = {
  program = {
    _loweredProgramStorage = nil
    tree = {
      root = convertedRegexLiteral
    }
    compileOptions = {
      rawValue = 0
    }
  }
}
  2> let regex2 = /(\w+Play)\(/
  3.     ^C
  2> let regex2 = "(\w+Play\("
error: error while processing module import: repl.swift:3:17: invalid escape sequence in literal
let regex2 = "(\w+Play\("
                ^

error: repl.swift:3:24: cannot find ')' to match opening '(' in string interpolation
let regex2 = "(\w+Play\("
                       ^

error: repl.swift:3:14: unterminated string literal
let regex2 = "(\w+Play\("
             ^



  2> let regex2 = "(\w+Play\\("
error: error while processing module import: repl.swift:3:17: invalid escape sequence in literal
let regex2 = "(\w+Play\\("
                ^



  2> let regex2 = "(\w+Play\\\("
error: error while processing module import: repl.swift:3:17: invalid escape sequence in literal
let regex2 = "(\w+Play\\\("
                ^

error: repl.swift:3:26: cannot find ')' to match opening '(' in string interpolation
let regex2 = "(\w+Play\\\("
                         ^

error: repl.swift:3:14: unterminated string literal
let regex2 = "(\w+Play\\\("
             ^



  2> let regex2 = "(\w+Play"
error: error while processing module import: repl.swift:3:17: invalid escape sequence in literal
let regex2 = "(\w+Play"
                ^



  2> let regex2 = "(\w+Play)"
error: error while processing module import: repl.swift:3:17: invalid escape sequence in literal
let regex2 = "(\w+Play)"
                ^

FWIW it works if you do:

let regex = /(\w+Play)\(/;

or:

let regex = #/(\w+Play)\(/#

Looks like the issue is that LLDB is calling into ide::isSourceInputComplete in the compiler, but not passing along any language options, so the compiler doesn't know that bare slash regex is enabled. Filed LLDB doesn't pass through language options to `ide::isSourceInputComplete` · Issue #9430 · swiftlang/llvm-project · GitHub

5 Likes

Thanks, pal!

Put up PRs to fix:

4 Likes