正则表达式帮助需要解析 mediawiki 模板 Javascript
Regexp assistance needed parsing mediawiki template with Javascript
我正在使用 Javascript 处理 Mediawiki 标记。我正在尝试删除某些参数。我无法准确找到要删除的文本,而且只能找到我要删除的文本。
简化下来,模板文本可以是这样的:
{{TemplateX
| a =
Foo bar
Blah blah
Fizbin foo[[domain:blah]]
Ipsum lorem[[domain:blah]]
|b =1
|c = 0fillertext
|d = 1alphabet
| e =
| f = 10: One Hobbit
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
| j = Level 4 [[domain:filk|Songs]]
| k =7 fizbin, 8 [[domain:trekkies|Shatners]]
|l =
|m =
}}
到目前为止我想到的最好的是
/\|\s?(a|b|d|f|j|k|m)([^][^\n\|])+/gm
更新版本:
/\|\s?(a|b|d|f|j|k|m)(?:[^\n\|]|[.\n])+/gm
给出(更新后的正则表达式):
{{TemplateX
|c = 0fillertext
| e =
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
|Songs]]
|Shatners]]
|l =
但我想得到的是:
{{TemplateX
|c = 0fillertext
| e =
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
|l =
}}
我可以处理多余的换行符,但我仍然需要确保“|Songs]]”和“|Shatners]]”也与正则表达式匹配。
关于下面 Tgr 的评论,
为了我的目的,可以安全地假设每个参数都在一个新行开始,其中 |是该行的第一个字符,并且没有参数定义包含 |那不在 [[foo|bar]] 结构中。所以 '\n|'是安全的 "start" 和 "stop" 序列。所以问题归结为,对于任何给定的参数(问题中的 a、b、d、f、j、k 和 m),我需要一个匹配以下 'wanted param' 的正则表达式:
| [other param 1] = ...
| [wanted param] = possibly multiple lines and |s that aren't after a newline
| [other param 2]
您可以在下面尝试这个 - 它匹配您想要包含的变量,而不是那些您想要排除的变量:
(^{{TemplateX)|\|\s*(c|e|g|h|i|l[ ]*\=[ ]*)(.*)|(}}$)
编辑
我增强了它,我认为如果你使用图表工具比较两个正则表达式会更好 regexper.com:
(^{{TemplateX)|(\|[ ]*)(c|e|g|h|i|l)([ ]*\=[ ]*)(.*)|(}}$)
编辑 2
根据评论,匹配不需要的参数的正则表达式是这样的:
\|[ ]?(a|b|d|f|j|k|m)([ ]*\=[ ]*)((?![\r\n]+\|)[0-9a-zA-Z, \[\]:\|\r\n\t])+
利用此 answer - 它使用否定前瞻来仅匹配 [\r\n]+\|
这将部分满足以下声明:
So '\n|' is a safe "start" and "stop" sequence
Tested here 在要保留的参数中引入了一些换行符(例如 g
)。
视觉解释:
您的参数值可能包含
以外的字符
[0-9a-zA-Z, \[\]:\|\r\n\t]
要解决这个问题,您需要更新该列表。
试图解释模板语言的全部灵活性是没有希望的。例如,模板可能看起来像
{{TemplateX
| a=1 | b=2 }}
或
{{TemplateX|
| a=1 <nowiki>|</nowiki> b=2 }}
完全不同(第一个有两个参数,a
和b
,第二个只有一个a
参数)。正则表达式(大部分)是上下文无关的,无法理解这样的结构。
所以除非你确定模板总是按照相同的约定使用,否则你最好使用一些合适的解析器,例如 mwparserfromhell:
import mwparserfromhell
wikicode = mwparserfromhell.parse(text)
for template in wikicode.filter_templates(recursive=True, matches=lambda t: t.name.strip() == 'TemplateX'):
for param in ['a', 'b', 'd', 'f', 'j', 'k', 'm']:
template.remove(param)
print(wikicode)
(这需要在 Python 中重写代码或调用 Python 后端服务。我认为 Javascript 中没有任何好的 wikitext 解析器。)
或者,您可以将 parse API 与 prop=parsetree
一起使用以获得模板及其参数的 XML 树表示,这并不难处理。
我正在使用 Javascript 处理 Mediawiki 标记。我正在尝试删除某些参数。我无法准确找到要删除的文本,而且只能找到我要删除的文本。
简化下来,模板文本可以是这样的:
{{TemplateX
| a =
Foo bar
Blah blah
Fizbin foo[[domain:blah]]
Ipsum lorem[[domain:blah]]
|b =1
|c = 0fillertext
|d = 1alphabet
| e =
| f = 10: One Hobbit
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
| j = Level 4 [[domain:filk|Songs]]
| k =7 fizbin, 8 [[domain:trekkies|Shatners]]
|l =
|m =
}}
到目前为止我想到的最好的是
/\|\s?(a|b|d|f|j|k|m)([^][^\n\|])+/gm
更新版本:
/\|\s?(a|b|d|f|j|k|m)(?:[^\n\|]|[.\n])+/gm
给出(更新后的正则表达式):
{{TemplateX
|c = 0fillertext
| e =
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
|Songs]]
|Shatners]]
|l =
但我想得到的是:
{{TemplateX
|c = 0fillertext
| e =
| g = aaaa, bbbb, cccc, dddd
|h = 15000
|i = -15000
|l =
}}
我可以处理多余的换行符,但我仍然需要确保“|Songs]]”和“|Shatners]]”也与正则表达式匹配。
关于下面 Tgr 的评论,
为了我的目的,可以安全地假设每个参数都在一个新行开始,其中 |是该行的第一个字符,并且没有参数定义包含 |那不在 [[foo|bar]] 结构中。所以 '\n|'是安全的 "start" 和 "stop" 序列。所以问题归结为,对于任何给定的参数(问题中的 a、b、d、f、j、k 和 m),我需要一个匹配以下 'wanted param' 的正则表达式:
| [other param 1] = ...
| [wanted param] = possibly multiple lines and |s that aren't after a newline
| [other param 2]
您可以在下面尝试这个 - 它匹配您想要包含的变量,而不是那些您想要排除的变量:
(^{{TemplateX)|\|\s*(c|e|g|h|i|l[ ]*\=[ ]*)(.*)|(}}$)
编辑
我增强了它,我认为如果你使用图表工具比较两个正则表达式会更好 regexper.com:
(^{{TemplateX)|(\|[ ]*)(c|e|g|h|i|l)([ ]*\=[ ]*)(.*)|(}}$)
编辑 2
根据评论,匹配不需要的参数的正则表达式是这样的:
\|[ ]?(a|b|d|f|j|k|m)([ ]*\=[ ]*)((?![\r\n]+\|)[0-9a-zA-Z, \[\]:\|\r\n\t])+
利用此 answer - 它使用否定前瞻来仅匹配 [\r\n]+\|
这将部分满足以下声明:
So '\n|' is a safe "start" and "stop" sequence
Tested here 在要保留的参数中引入了一些换行符(例如 g
)。
视觉解释:
您的参数值可能包含
以外的字符[0-9a-zA-Z, \[\]:\|\r\n\t]
要解决这个问题,您需要更新该列表。
试图解释模板语言的全部灵活性是没有希望的。例如,模板可能看起来像
{{TemplateX
| a=1 | b=2 }}
或
{{TemplateX|
| a=1 <nowiki>|</nowiki> b=2 }}
完全不同(第一个有两个参数,a
和b
,第二个只有一个a
参数)。正则表达式(大部分)是上下文无关的,无法理解这样的结构。
所以除非你确定模板总是按照相同的约定使用,否则你最好使用一些合适的解析器,例如 mwparserfromhell:
import mwparserfromhell
wikicode = mwparserfromhell.parse(text)
for template in wikicode.filter_templates(recursive=True, matches=lambda t: t.name.strip() == 'TemplateX'):
for param in ['a', 'b', 'd', 'f', 'j', 'k', 'm']:
template.remove(param)
print(wikicode)
(这需要在 Python 中重写代码或调用 Python 后端服务。我认为 Javascript 中没有任何好的 wikitext 解析器。)
或者,您可以将 parse API 与 prop=parsetree
一起使用以获得模板及其参数的 XML 树表示,这并不难处理。