scala,字符串变量处理为字符串而不是regexp

时间:2013-04-09 10:08:31

标签: string scala replace

可以无缝地做到吗?

 scala> val p = "$"
 scala> "hello, I have 65 dollars".replaceFirst("dollars", p)

目前的结果是

 java.lang.StringIndexOutOfBoundsException: String index out of range: 1
 ....

scala 2.10中的预期结果:

 hello, I have 65 $

问题在于存储符号p的变量$,我需要将其作为字符串处理而不是regexp。

注意: 我无法修改(例如替换所有非字母符号)p变量(仅限标准函数,例如.toString)

注2:给定的例子是玩具示例。我很欣赏一个更通用的解决方案。即变量p可以包含任何类型的内容(符号,数字,文本......),因此将“$”替换为“\\ $”并不是很有意义

(这是类似问题的改进版本:scala string, raw string

3 个答案:

答案 0 :(得分:2)

你需要逃避美元符号字面值,因为Java uses it in its implementation of regular expressions as a group reference

您注意到您无法修改p变量中的字符串文字,因此您需要使用替换美元符号和其他特殊字符,例如this

Pattern.quote(p);

答案 1 :(得分:2)

对模式使用Regex.quote,对替换字符串使用quoteReplacement。 (这些只是调用Pattern。)

scala> import util.matching._
import util.matching._

scala> "hello, I have 65 dollars".replaceFirst("dollars", Regex quoteReplacement p)
res7: String = hello, I have 65 $

scala> "dollars".r replaceFirstIn ("hello, I have 65 dollars", Regex quoteReplacement p)
res8: String = hello, I have 65 $

scala> "hello, I have 65 dollars".replaceAllLiterally("dollars", p) // quotes both
res9: String = hello, I have 65 $

答案 2 :(得分:1)

问题是replaceFirst()使用正则表达式:

"65 dollars".replaceFirst("dollars","$0") // compiles
"65 dollars".replaceFirst("dollars","$")  // throws "StringIndexOutOfBoundsException"

如果,

val dollars = "$"

你可以逃避$符号,

"65 dollars".replaceFirst( "dollars", if(dollars == "$") "\\$" else dollars )

或使用字符串插值,

s"65 $dollars"

或去旧学校字符串操作,

val t = "65 dollars".split("dollars"); if(t.size>1) t.mkString(dollars) else t(0) + dollars

或使用地图

val ff = "dollars"
val r1 = "$"
"65 dollars, 3 dollars, 50 dollars".split(ff).zipWithIndex.map{case (t,0) => t+r1; case (t,_) => t+ff}.mkString