我以字符串的形式输入,如下所示
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 {'或'指向{',
但这不起作用......
很可能有办法做我想要的,但正如我所说,我不是正则表达的专家。如果您对我有答案,我将非常感谢您的解释,因为我想了解解决方案。 提前谢谢!
答案 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()))))))