带有wiki文本的Python正则表达式

带有wiki文本的Python正则表达式,python,regex,wiki,Python,Regex,Wiki,我正在尝试使用Python正则表达式替换将wikitext更改为普通文本。关于wiki链接,有两种格式规则 [[页面名称]] [[页面名称|要显示的文本]] (http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet) 这里有一些让我头疼的文字 这张CD几乎全部由乔治·马丁(George Martin)[唱片制作人|制作的]]最初创作的[[披头士]]歌曲的[[封面版本]]组成 上述案文应改为: 这张CD几乎全部由乔治·马丁最初制作的披头士歌曲的封面版

我正在尝试使用Python正则表达式替换将wikitext更改为普通文本。关于wiki链接,有两种格式规则

  • [[页面名称]]
  • [[页面名称|要显示的文本]]

    (http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet)

这里有一些让我头疼的文字

这张CD几乎全部由乔治·马丁(George Martin)[唱片制作人|制作的]]最初创作的[[披头士]]歌曲的[[封面版本]]组成

上述案文应改为:

这张CD几乎全部由乔治·马丁最初制作的披头士歌曲的封面版本组成

[[]]和[[|]]语法之间的冲突是我的主要问题。我不需要一个复杂的正则表达式。按顺序应用多个(可能两个)正则表达式替换是可以的


请告诉我这个问题。

我想出了一个正则表达式,可以解决这个问题。如果有什么问题,请告诉我:

r"\[\[(([^\]|]|\](?=[^\]]))*)(\|(([^\]]|\](?=[^\]]))*))?\]\]"
(哎呀,我永远也忘不了这些东西有多难看!)

第1组应该为您提供wiki链接。第4组应提供链接文本,如果没有管道,则无链接文本

解释:

  • (([^\].].\](?=[^\]])*)
    查找所有非“|”或“]]”字符序列。它通过查找所有不是“|”或“]”或“的字符序列来实现这一点,这些字符序列后面是一个不是“]”的字符
  • (\\;([^\]\\](?=[^\]]))*)?
    可以选择匹配一个“|”后跟与上面相同的正则表达式,以获取链接文本部分。正则表达式稍有改动,因为它允许使用“|”字符
  • 很明显,整个过程都被
    \[\[
    \]\]
    包围着
  • (?=…)
    表示法与正则表达式匹配,但不使用其字符,因此可以随后进行匹配。我使用它是为了不使用可能在“]”之后立即出现的“|”字符
编辑:我修复了正则表达式,允许在“|”前面加一个“]”,如
[[abcd]| efgh]
中所述

wikilink_rx = re.compile(r'\[\[(?:[^|\]]*\|)?([^\]]+)\]\]')
return wikilink_rx.sub(r'\1', the_string)
例如:

注意:您还可以在中找到一些MediaWiki解析器。

这应该可以工作:

text = "The CD is composed almost entirely of [[cover version]]s of [[The Beatles]] songs which George Martin [[record producer|produced]] originally."
newText = re.sub(r'\[\[([^\|\]]+\|)?([^\]]+)\]\]',r'\2',text)

你走错了路。众所周知,Wiki标记很难解析,并且存在太多异常、边缘情况和简单的标记,因此构建自己的正则表达式来解析几乎是不可能的。由于您使用的是Python,我建议您使用mwlib,它将为您完成艰巨的工作:


不支持包含“]”字符的链接。我不知道这是否是MediaWiki语法的一部分,但我的回答确实允许这样做(代价是读起来有点难!)我的和@KennyTM之间的一个区别是,虽然我的同时提供页面名称和链接文本,但Kenny的只提供链接文本——但是,如果没有“|”,Kenny's会将页面名称作为链接文本提供给您,这可能是您想要的。请注意我对他的评论。谢谢你的回答。你善意的解释真的帮了我的忙。有一个语法分析器:有一个正则表达式可以同时解析[[]]和[[|]]语法,其实并不比只解析[[|]]语法更复杂,所以你最好就有一个。