2

Considering a path such as

var dir = new File("""c:\test\project1""");

How do I easily in Scala escape/quote this so it can be used safely in regular expressions

val extractRelativePath = (dir.getAbsolutePath() + """(.*)""").r

I tried using

dir.getAbsolutePath().replaceAll("\\", "\\\\");

but this does not work. as the following example shows

def main(args: Array[String]): Unit = {
  var base = new File("""c:\test\project1""");
  val extractRelativePath = (base.getAbsolutePath() + """(.*)""").r

  var dir = new File("""c:\test\project1\somedir""");
  var extractRelativePath(rel) = dir.getAbsolutePath().replaceAll("\\\\", "\\\\")
}

Also is there not some standard functionality that does this safely across platforms like Pattern.quote ?.

tenshi
  • 26,268
  • 8
  • 76
  • 90
Lars Tackmann
  • 20,275
  • 13
  • 66
  • 83

2 Answers2

2

You can use quotations, but I think that in your case you also need to escape \E. Following code should do it:

("""\Q""" + base.getAbsolutePath.replaceAll("\\\\E", "\\\\E\\\\\\\\E\\\\Q") + """\E(.*)""").r

I generally replacing \E with \E\\E\Q, so I split quotation and explicitly adding \\ followed by E in regexp.

Here is small example. If I have defined base like his:

var base = new File("""c:\test\Earth""");

then it will produce following regexp:

\Qc:\test\E\\E\Qarth\E(.*)

As an advantage to this approach, \Q and \E will escape everything and not only * or \.


Here is the whole example code:

var base = new File("""c:\test\Earth""");
val extractRelativePath = ("""\Q""" + base.getAbsolutePath.replaceAll("\\\\E", "\\\\E\\\\\\\\E\\\\Q") + """\E(.*)""").r

var dir = new File("""c:\test\Earth\somedir""");
var extractRelativePath(rel) = dir.getAbsolutePath

println(rel) // prints: \somedir 

By the way

You can also use Pattern.quote which makes exactly the same, but more efficiently:

(Pattern.quote(base.getAbsolutePath) + """(.*)""").r
tenshi
  • 26,268
  • 8
  • 76
  • 90
1

Looks funny, but it should at least escape the backslashes.

replaceAll("\\\\", "\\\\")

But what you should use is Pattern.quote. See this question.

Community
  • 1
  • 1
Kim Stebel
  • 41,826
  • 12
  • 125
  • 142