Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中搜索替换为正则表达式组的最简单方法_Scala - Fatal编程技术网

在Scala中搜索替换为正则表达式组的最简单方法

在Scala中搜索替换为正则表达式组的最简单方法,scala,Scala,假设我有一个正则表达式,它有一个捕获组。在scala中有没有一种简单的方法可以用替换字符串替换这个捕获组?我只能找到用一些内容替换整个正则表达式的功能,这些内容可能包括一个捕获组,但替换的字符串中不包含完整的正则表达式匹配项。举一个具体的例子: val p = """^[bf]oo: '(.*)'"""r println(p.replaceFirstGroup("foo: 'replace me'", "asdf")) // something like this 有输出 foo: 'asdf

假设我有一个正则表达式,它有一个捕获组。在scala中有没有一种简单的方法可以用替换字符串替换这个捕获组?我只能找到用一些内容替换整个正则表达式的功能,这些内容可能包括一个捕获组,但替换的字符串中不包含完整的正则表达式匹配项。举一个具体的例子:

val p = """^[bf]oo: '(.*)'"""r
println(p.replaceFirstGroup("foo: 'replace me'", "asdf")) // something like this
有输出

foo: 'asdf'

使用lookahead和lookahead(如的定义)以及将为您提供所需的结果:

val p = """(?<=^[bf]oo: ').*(?=')"""
println("foo: 'replace me'".replaceFirst(p, "asdf"))
// => foo: 'asdf'
我知道从技术上讲,这并不能取代第一个捕获组,但“向前看”和“向后看”总是让我觉得自己很脏。(我知道,讽刺的是,我们已经在这里使用正则表达式了!)


我希望能提出一些其他的东西,因为前瞻限制了前瞻部分中正则表达式的复杂性,匹配多个组会给提取器和替换代码增加额外的复杂性

这要实现起来有点麻烦(您必须编写一些额外的代码),但它可以保持提取器的整洁,同时避免lookaheads/lookbehinds:

import scala.util.matching.Regex

implicit class MyRegExOps(val pattern: Regex) extends AnyVal {
  def replaceFirstGroup(target: String, replacement: String): Option[String] = {
    for (matched <- pattern.findFirstMatchIn(target))
      yield "%s%s%s".format(
        matched.group(0).substring(0, matched.start(1)),
        replacement,
        matched.group(0).substring(matched.end(1)))
  }
}

// Notice that the next two lines exactly match your original post
val p = """^[bf]oo: '(.*)'"""r
println(p.replaceFirstGroup("foo: 'replace me'", "asdf"))
// => Some(foo: 'asdf')
import scala.util.matching.Regex
隐式类MyRegExOps(val模式:Regex)扩展了AnyVal{
def replaceFirstGroup(目标:字符串,替换:字符串):选项[String]={
对于(匹配一些(foo:'asdf')
也许这个方法在这里有用

(引用ScalaDoc的例子):

就你而言:

val p = """^([bf]oo): '(.*)'"""r
val map = Map("foo" -> "foo: 'asdf'")
val lines = List("boo: 'bar' and beyond","foo: 'yuck' whatever")
val mapper = (m: Match) => map get (m group 1) map (quoteReplacement(_))

scala> val repl = text map { line => p replaceSomeIn(line, mapper) }
m: boo: 'bar' boo
m: foo: 'yuck' foo
repl: List[String] = List(boo: 'bar' and beyond, foo: 'asdf' whatever)

谢谢,我看到了这个方法,但它似乎涉及到在替换字符串中使用组,而不是用替换字符串替换组。它似乎也可以用来替换组(如果我正确理解您想要实现的目标),但我同意它看起来很奇特。你有链接吗?我找不到任何使用此方法替换组的方法。我认为foo到“foo plus replacement”的“硬编码”映射是欺骗。另一个答案表明API不容易推广。哈,我提出了与变通方法完全相同的两个解决方案。我希望提出其他解决方案,因为前瞻限制了前瞻部分中正则表达式的复杂性,匹配多个组会增加提取器和repl的额外复杂性acement代码。@jonderry-添加了另一种可能的方法,您可以仔细考虑。令人惊讶的尴尬。让我说清楚,我可以替换整个模式,但要替换组,我必须做算术?自从通过A.P.算术考试以来,我就没有做过算术。@som snytt-您不必做任何算术(如果你想把字符串分成子字符串)因为我已经写了这部分了!但是,如果你想在不使用多个捕获组的情况下操作匹配的字符串,你会被困在这样的操作中。
import scala.util.matching.Regex._

val map = Map("x" -> "a var", "y" -> """some $ and \ signs""")
val text = "A text with variables %x, %y and %z."
val varPattern = """%(\w+)""".r
val mapper = (m: Match) => map get (m group 1) map (quoteReplacement(_))
val repl = varPattern replaceSomeIn (text, mapper)
val p = """^([bf]oo): '(.*)'"""r
val map = Map("foo" -> "foo: 'asdf'")
val lines = List("boo: 'bar' and beyond","foo: 'yuck' whatever")
val mapper = (m: Match) => map get (m group 1) map (quoteReplacement(_))

scala> val repl = text map { line => p replaceSomeIn(line, mapper) }
m: boo: 'bar' boo
m: foo: 'yuck' foo
repl: List[String] = List(boo: 'bar' and beyond, foo: 'asdf' whatever)