【问题标题】:Scala: Regex that matches everything up to a certain characterScala:匹配所有内容到某个字符的正则表达式
【发布时间】:2018-02-26 21:57:02
【问题描述】:

我希望我的正则表达式打印 { 或 {{ 之前的所有内容(不包括它们。

到目前为止我所拥有的是:

class ExpressionParser extends RegexParsers {

    val regExpr = """^.*?((?=\{{2})|(?=\{)|$)""".r //not sure about the "$". Added it because test case 1 wasn't printing. see below
    def program: Parser[Any] = regExpr
}

这是我的测试:

object Test {
    def main(args: Array[String]): Unit = {

        val p = new ExpressionParser()
        val test = p.parseAll(p.program, 'tests go here') // doesn't print anything
        if(test.successful) println(test.get)

// 用其中的每一个替换 'tests go here'

        //"This is plain text so should always print") // this isn't printing so make checks for { optional
        //"abc {{"
        //"abc  de{ fg{{{ hi"
        //"abc } {{ {{ de{' fg{{{ hi")
    }
}

我希望它打印出来:

//This is plain text so should always print
//abc 
//abc  de
//abc {

仅打印第一个测试。为什么?

谢谢!

【问题讨论】:

  • 我用班级的内容编辑了帖子
  • 请提供minimal reproducible example。不清楚你编码了什么,在哪里声明/定义了什么。
  • 我编辑了整个内容。现在更清楚了

标签: regex scala pattern-matching lookahead negative-lookahead


【解决方案1】:

在海报变得更加具体后,向下滚动以进行编辑以显示答案

我从未听说过 Scala API 中内置了 ExpressionParser,但如果您想将所有内容都达到某个特定点或介于两件事之间,您可以使用

(?s)(.*)

所以要获得字母“a”之前的所有内容,您可以使用...

(?s)(.*)a

代码示例:

  val regex2 = """(?s)(.*)a""".r

  val str1 = "somethinga"
  str1 match {
    case regex2(left) => println(left)
  }

这将打印不带引号的“某物”

编辑: 由于您现在已经更新了答案以表明您正在使用 RegexParsers,因此这里将提供一个使用该解决方案的解决方案,但如果这就是您使用 RegexParsers 的全部目的,那么这将是一个非常过分且不必要的解决方案。

class ExpressionParser extends RegexParsers {
  def remover: Parser[String] = """.*(?=\{)|.*""".r
}

主要:

val p = new ExpressionParser()
val test = p.parseAll(p.remover, "tests go here{")// doesn't print anything
if (test.successful) println(test.get) // prints "tests go here"

能够通过阅读此处的 RegexParser 文档来解决这个问题: https://github.com/scala/scala-parser-combinatorshttps://github.com/scala/scala-parser-combinators/blob/1.1.x/docs/Getting_Started.md

如果文档仍然没有意义,则对此进行解释,这是使用“前瞻组”解决的,该组将先于前一个组查找与前瞻组匹配的模式并将其从结果中排除。

因此,一旦您点击 {,它将匹配直到 { 的所有内容的表达式并返回。

现在的原因|是它最初会尝试匹配“后面跟着{”的所有内容,但如果不匹配,就会出现问题。因此,我们必须使用“或(|)”来表示如果没有{,则使用所有内容。

为什么我们不能只添加一个?到左边部分|在前瞻组的末尾,使前瞻组可选是它实际上不会删除前瞻组。如果你想用这个正则表达式,你可以试试看。

.*(?=\{)?

【讨论】:

  • 谢谢!我还没来得及测试你的建议,但我用课程的内容和 parseAll 的类型编辑了帖子
猜你喜欢
  • 2020-03-16
  • 2017-09-02
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
相关资源
最近更新 更多