scala正则表达式过滤器包裹的元素

时间:2015-10-22 15:57:47

标签: regex scala

我以字符串的形式输入,如下所示

ellipse {
    attribute = foo

    ellipse {
        attribute = foo
        line {
            attribute = foo
            attribute = foo
            attribute = foo
        }
        line {
            attribute = foo
            attribute = foo
        }
    }
}

基本上它是关于2d元素,能够容纳其中的其他2d元素。我的任务是编写一个正则表达式,它可以从子项中分离父元素,因此可以单独解析它们。 在以下情况下:

rectangle1{
    attribute = foo
}
ellipse1{
    attribute = foo
    ellipse{
        rectangle{
            attribute = foo
        }
    }
}

我希望能够regex.findAllIn(string)然后只有rectangle1和ellipse1字符串,所以我可以解析它们。 我不是正则表达的专家,但我做了一个尝试,当然失败了:

我试图:

  

(?s)(?!((ellipse | point | line)\\ {))。+ (ellipse | point | line) \\ {。* \\}

获取所有椭圆或点或线,

  

(?s)(?!((ellipse | point | line)\\ {))。+(ellipse | point | line) \\ {。* \\}

包含一些内容,但

  

(?s)(?!((ellipse | point | line)\\ {))。+(ellipse | point | line)\\ {。* \\}

  

(?s)(?!((ellipse | point | line)\\ {))。+(ellipse | point | line)\\ {。* \\}

上面有'ellipse {''指向{'

但这不起作用......

很可能有办法做我想要的,但正如我所说,我不是正则表达的专家。如果您对我有答案,我将非常感谢您的解释,因为我想了解解决方案。 提前谢谢!

1 个答案:

答案 0 :(得分:2)

纯正则表达式不适合这项任务。你必须使用递归正则表达式,Java(以及因此Scala)目前不支持它们。

但是,当您使用Scala时,您可以利用功能强大的Parser Combinator库:

object ParserCombinator extends App with JavaTokenParsers with PackratParsers {

  case class Attr(value:String)
  case class Fig2d(name:String, attrs:List[Attr], children:List[Fig2d])

  def fig2d:Parser[Fig2d] = (ident <~ "{") ~ rep(attr) ~ (rep(fig2d) <~ "}") ^^ {
    case name ~ attrs ~ children => Fig2d(name, attrs, children)
  }

  def attr:Parser[Attr] = "attribute" ~> "=" ~> "\\S+".r ^^ Attr.apply

  def fig2dList = rep(fig2d)

  val input =
    """
      |rectangle1{
      |    attribute = foo
      |}
      |ellipse1{
      |    attribute = foo
      |    ellipse{
      |        rectangle{
      |            attribute = foo
      |        }
      |    }
      |}
    """.stripMargin


  println(parseAll(fig2dList, input))
}

打印:

 [13.5] parsed: List(Fig2d(rectangle1,List(Attr(foo)),List()), Fig2d(ellipse1,List(Attr(foo)),List(Fig2d(ellipse,List(),List(Fig2d(rectangle,List(Attr(foo)),List()))))))