2014-09-05 63 views
0

我已经喜欢斯卡拉更换由正则表达式

val bar = "M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo". 

字符串现在我拆分此字符串并定义图案

val split = bar.split("-") 
val pattern = ".*(A|K)\\d.*".r 

,现在我想更换A9K9foo在“分裂的最后一个条目“

val last = split.last 
val suffix = last match { 
    case pattern(_) => last replaceFirst ("""(A\d)?(K\d)?.*""", "") 
    case _   => last 
} 

我所知道的是,replaceFirst被执行,但它不会在我的替代A9K9foo‘最后’VAL (REPL aceFirst应该只在'last'匹配'pattern'时执行),通缉的结果是M2。

编辑:它可能发生的最后不是M9A9K9foo,而是M9A9或M9K9foo或M9A9K9。我想要的只是替换除A \ d或K \ d之前的文本之外的所有内容,但如果没有A \ d或K \ d,则不会发生任何事情。

你知道为什么这个替换不起作用吗?

+0

非常奇怪的事情想要做,你能提供更多的上下文,我们可能能够建议一个完全不同的方式 - 希望避免正则表达式! :) – samthebest 2014-09-07 03:59:07

+0

没有更多的上下文,我只想每次的M9字符串 – ChampS 2014-09-07 07:05:31

回答

0

您正在使用String.replaceFirst,并且您的模式具有消耗所有内容的通配符。

也许你想:

last replaceFirst ("""A\dK\d""", "") 

其中A9K9不可选的,这就是你要替换。

还有其他配方:

scala> val r = """(A\dK\d)""".r 
r: scala.util.matching.UnanchoredRegex = (A\dK\d) 

scala> val m = (r findAllMatchIn bar).toList.last 
m: scala.util.matching.Regex.Match = A9K9 

scala> s"${m.before}${m.after}" 
res15: String = M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9foo 

这不是最聪明的。

更多:

scala> val r = """(A|K)\d""".r 
r: scala.util.matching.Regex = (A|K)\d 

scala> val bar = "M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo" 
bar: String = M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo-M9A9K9foo 

scala> val last = (bar split "-").last 
last: String = M9A9K9foo 

scala> r findFirstMatchIn last map (_.before) getOrElse last 
res0: CharSequence = M9 

scala> val r = """(.*?)((A|K)\d.*)?""".r 
r: scala.util.matching.Regex = (.*?)((A|K)\d.*)? 

scala> last match { case r(prefix, _*) => prefix } 
res1: String = M9 

scala> "M9" match { case r(prefix, _*) => prefix } 
res2: String = M9 

scala> "M9K9foo" match { case r(prefix, _*) => prefix } 
res3: String = M9 

scala> val r = """(.*?)(?:(?:A|K)\d.*)?""".r 
r: scala.util.matching.Regex = (.*?)(?:(?:A|K)\d.*)? 

scala> last match { case r(prefix) => prefix } 
res4: String = M9 

诊断是相同的;有不同的方式拉开字符串。

+0

A \ D和K \ D是可选的。 M9A9K9foo也可以是M9A9foo或M9K9foo或M9A9K9。但如果它只是M9,则什么都不应该被取代。 什么是replaceFirst的问题? 我想替换第一个A9或K9以及后面的任何文本,而不是匹配M9 – ChampS 2014-09-08 09:11:58

+0

replaceFirst没有错,但它本身就是Java API。我已经给你看了几个选项。拿它或离开它等等。不是脑部手术。 – 2014-09-08 14:18:35