在Java中使用正则表达式解析wikiText

3

假设有一个wikiText字符串,例如:

{{ValueDescription
    |key=highway
    |value=secondary
    |image=Image:Meyenburg-L134.jpg
    |description=A highway linking large towns.
    |onNode=no
    |onWay=yes
    |onArea=no
    |combination=
    * {{Tag|name}}
    * {{Tag|ref}}
    |implies=
    * {{Tag|motorcar||yes}}
    }}

我希望能够在Java/Groovy中解析模板ValueDescriptionTag。我尝试使用正则表达式/\{\{\s*Tag(.+)\}\}/,它很好用(它返回|name |ref|motorcar||yes),但是/\{\{\s*ValueDescription(.+)\}\}/不起作用(它应该返回上面的所有文本)。
期望的输出是:
有没有办法在正则表达式中跳过嵌套的模板?
理想情况下,我更愿意使用简单的wikiText 2 xml工具,但我找不到类似的东西。
谢谢! Mulone

1
请问您能否提供一些您所期望从上述输入中得到的样例输出? - anubhava
2个回答

4
任意嵌套标签是不可行的,因为这会使语法变得非正则。你需要使用能够处理上下文无关语法的工具。ANTLR 是一个很好的选择。

2
使用Pattern.DOTALL选项创建您的正则表达式模式,格式如下:
Pattern p = Pattern.compile("\\{\\{\\s*ValueDescription(.+)\\}\\}", Pattern.DOTALL);

示例代码:

Pattern p=Pattern.compile("\\{\\{\\s*ValueDescription(.+)\\}\\}",Pattern.DOTALL);
Matcher m=p.matcher(str);
while (m.find())
   System.out.println("Matched: [" + m.group(1) + ']');

输出

Matched: [
|key=highway
|value=secondary
|image=Image:Meyenburg-L134.jpg
|description=A highway linking large towns.
|onNode=no
|onWay=yes
|onArea=no
|combination=
* {{Tag|name}}
* {{Tag|ref}}
|implies=
* {{Tag|motorcar||yes}}
]

更新

假设在{{ValueDescription后面,关闭}}出现在单独的一行,以下模式可以用来捕获多个ValueDescription

Pattern p = Pattern.compile("\\{\\{\\s*ValueDescription(.+?)\n\\}\\}", Pattern.DOTALL);

这个可以工作,但如果有另一个'''{{ValueDescription}}'''块,它就不会停止。 - Mulone
@Mulone:假设在“{{ValueDescription”后面的关闭“}}”出现在单独的一行上,以下模式将适用于捕获多个“ValueDescription”:“Pattern p = Pattern.compile("\{\{\s*ValueDescription(.+?)\n\}\}", Pattern.DOTALL);” - anubhava
我认为在阅读维基文本时,这种假设是无效的。有没有一种方法可以使它更加健壮? - Mulone
@Mulone: 正则表达式在这里确实有一些限制,你需要有一种模式来匹配。右括号}}必须放在单独的一行上,或者后面跟着其他可以在上述模式中使用的字符。要验证/匹配非正则文本,最终你将需要一个解析器工具或者需要自己编写解析器。 - anubhava

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接