我想在下面的字符串中将amt_2和amt_4替换为amt_ytd_2和amt_ytd_4。
scala> val a = "select amt_1, amt_2, amt_3, amt_4 from table"
a: String = select amt_1, amt_2, amt_3, amt_4 from table
scala> val reg = """(\d+)""".r
reg: scala.util.matching.Regex = (\d+)
我可以一次性替换所有的字符串,但是如何仅替换字符串中第二和第四出现的字符串?
scala> reg.replaceAllIn(a, "_ytd_$1")
res23: String = select amt__ytd_1, amt__ytd_2, amt__ytd_3, amt__ytd_4 from table
scala>
我尝试了以下类似操作,但未获得预期结果
scala> var x = 0
x: Int = 0
scala> reg.replaceAllIn(a, {x+=1; if(x%2==0) "ytd" else " " })
res24: String = select amt_ , amt_ , amt_ , amt_ from table
scala>
答案 0 :(得分:4)
您可以在守卫条件下进行模式匹配。
"amt_(\\d+)".r.replaceAllIn(a, _ match {
case m if m.group(1).toInt % 2 == 0 => s"amt__ytd_${m.group(1)}"
case m => m.group(0)
})
//res0: String = select amt_1, amt__ytd_2, amt_3, amt__ytd_4 from table
更新
您似乎想要第二和第四匹配,不一定是以_2
和_4
结尾的匹配。试试这个。
//string to modify
val a = "select amt_1, amt_2, amt_3, amt_4 from table"
//all the matches
val ms = "amt_(\\d+)".r.findAllMatchIn(a).toVector
//modify 2nd & 4th match (i.e. at index 1 & 3) if they exist
Vector(1,3).foldRight(a)(
(x,s) => ms.lift(x).fold(s)(m => s.patch(m.start(1), "_ydt_", 0)))
//res0: String = select amt_1, amt__ydt_2, amt_3, amt__ydt_4 from table
请注意,只有找到了这么多匹配项时,这才会修改索引3处的第4个匹配项。同样,对于索引为1的第二个匹配。因此,如果找到0个或1个匹配,则不会生成任何mod。如果找到2或3个匹配项,则仅制作1个mod(第二个匹配项)。
答案 1 :(得分:1)
尝试使用replaceSomeIn
val a = "select amt_1, amt_2, amt_3, amt_4 from table"
val reg = """(\d+)""".r
var c = 0
reg.replaceSomeIn(a, m => {
c = c+1
val x = m.group(0)
if ( c == 2 || c == 4)
Some("a")
else
Some(x)
})
答案 2 :(得分:0)
val a = "select amt_1, amt_2, amt_3, amt_4 from table"
val reg = """((?=\d)(?=[^13]))""".r
reg.replaceAllIn(a, "_ytd_$1")
尝试一下