可以无缝地做到吗?
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)
答案 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