用于在C#中解析Wikicode的正则表达式

时间:2009-07-28 11:24:03

标签: c# regex

我尝试解析维基百科的文章。我使用* page-articles.xml文件,他们以wikicode格式备份所有文章。为了去除格式并获取原始文本,我尝试使用正则表达式,但我不是很习惯它。我使用C#作为编程语言。 我尝试使用正则表达式的设计师Expresso,但我的智慧结束了。这就是我想要实现的目标:

该文本可包含以下结构: [[TextN]]或 [[Text1 | TextN]]或 [[文本1 |文本2 | ... | TextN]]

[[....]]模式可以出现在Texti中。我想用TextN替换这些结构

为了识别文本中的结构,我尝试了以下RegEx:

\[\[ ( .* \|?)* \]\]

Expresso似乎与这个一起运行并且无休止地循环。在5分钟后找到相对较小的文本,我取消了测试运行。

然后我尝试了更简单的东西,我想在括号之间捕捉任何东西:

\[\[ .* \]\]

但是当我有一条像:

这样的行
[[Word1]] text inbetween [[Word2]]

表达式返回整行,而不是

[[字1]]

[[字2]]

Regex-Experts的任何提示都可以解决这个问题吗?

提前致谢, 弗兰克

5 个答案:

答案 0 :(得分:5)

我不会使用正则表达式(因为它们不能很好地处理递归/嵌套)。

相反,我会用手解析文本 *,这在这种情况下并不是特别困难。

您可以将文字表示为元素的流,而每个元素都是

  • 纯文本
  • 标记

标记可能包含多个元素流,由|分隔。

elementStream ::= element*
element ::= chunk | tag
chunk ::= TEXT
tag ::= "[[" elementStream otherStreams "]]"
otherStreams ::= "|" elementStream otherStreams

您的解析器可以使用方法表示每个定义。因此,只要有可用文本且接下来的两个字符不是“]]”或“|”,您就会有elementStream方法调用element (如果你在标签内)。 每次调用element都会返回解析的元素,无论是块还是标记。等

这基本上是一个递归下降解析器。 维基百科:http://en.wikipedia.org/wiki/Recursive_descent_parser(不幸的是,文章很长/很复杂)

答案 1 :(得分:3)

\[\[(.*?\]\]会这样做。

关键是。*?这意味着获得任何角色,但尽可能少。

修改

对于嵌套标签,一种方法是:

\[\[(?<text>(?>\[\[(?<Level>)|\]\](?<-Level>)|(?! \[\[ | \]\] ).)+(?(Level)(?!)))\]\]

这样可以确保[[和]]在整个文本中匹配。

答案 2 :(得分:1)

这是因为正则表达式尝试始终找到可能的最长匹配。您应该更改.*

尝试使用

\[\[([A-Za-z][A-Za-z\d+]*)(\|\1)*\]\]

这只匹配字母,|符号和双括号中的数字+它会检查值是否以字母开头。

答案 3 :(得分:0)

如果Expresso没有为您服务,您可能需要尝试RegexBuddy

虽然不是免费的,但它确实提供了一个出色的实时测试环境,您可以在其中查看正则表达式如何与示例文本的一部分匹配。

答案 4 :(得分:0)

如果GPL2不是您的问题,也许您可​​以查看Screwturn Wiki的源代码,看看专家是如何做到的。它在C#,BTW