Python 在正则表达式匹配中插入字符串
我需要将字符串Python 在正则表达式匹配中插入字符串,python,regex,string,match,Python,Regex,String,Match,我需要将字符串Special:MyLanguage/插入像[[ACBDEF]]这样的字符串,使其成为[[Special:MyLanguage/ABCDEF]] 问题是,我需要排除某些不应插入Special:MyLanguage/的匹配项: 已包含Special:MyLanguage/或 类别:或 文件:或 图像: 因此,用\[\[\[Special:MyLanguage/替换\[\[\[\[\[^(Special:MyLanguage | File:| Image:| Category:)]
Special:MyLanguage/
插入像[[ACBDEF]]
这样的字符串,使其成为[[Special:MyLanguage/ABCDEF]]
问题是,我需要排除某些不应插入Special:MyLanguage/
的匹配项:
- 已包含
或Special:MyLanguage/
或类别:
或文件:
图像:
因此,用
\[\[\[Special:MyLanguage/
替换\[\[\[\[\[^(Special:MyLanguage | File:| Image:| Category:)]
不起作用,因为它包含第一个字符(匹配项为[[a
)。我已经阅读了很多教程,尝试过使用$1
和\G
之类的东西,但我还是有些挠头。您可以使用负面前瞻来确保这些子字符串不会在[[
之后立即出现:
(\[\[)(?!Special:MyLanguage/|File:|Image:|Category:)(.*?]])
并替换为\1专用:MyLanguage/\2
。请参阅
详细信息
-组1:(\[\[)
子字符串[[
-在(?!Special:MyLanguage/| File:| Image:| Category:)
[[[/code>后面不能跟在替换组中列出的任何子字符串后面
-第2组:除换行符以外的任何0+字符,尽可能少,后跟(.*?]])
]]
[[Special:MyLanguage/text]]
[[File:text]]
[[Image:text]]
[[Category:text]]
[[Special:MyLanguage/Text and ]]
['[[Special:MyLanguage/ACBDEF]]', '[[Special:MyLanguage/ACBDEF]]', '[[Category:ACBDEF]]', '[[File:ACBDEF]]', '[[Special:MyLanguage/OneLasttest]]']
如果您不想弄乱正则表达式,这里有一个更简单的解决方案
exclusions = ["Special:MyLanguage/:","Category:","File:","Image:"]
# repl_str = "Special:MyLanguage/:"
def replace_str(str, repl_str):
for ex in exclusions:
if ex in str:
return
str = str[:2] + repl_str + str[2:]
假设它们都完全遵循您提供的模式:[[something]],并且它们将像您的问题一样插入
对于这样一个简单的例子,我发现正则表达式过于复杂,特别是在使用lookaheads、lookbehinds和使用捕获组时。尽可能地保持简单,节省算法复杂性,以便在真正需要的时候使用。你可以使用
re.sub
和re.findall
:
import re
tests = ['[[ACBDEF]]', '[[Special:MyLanguage/ACBDEF]]', '[[Category:ACBDEF]]', '[[File:ACBDEF]]', '[[OneLasttest]]']
def isvalid(lang):
return not re.findall('^Special:MyLanguage/|^File|^Category|^Image', lang)
final_results = [re.sub('(?<=\[\[)[\w\W]+(?=\]\])', '{}', i).format(*['Special:MyLanguage/'+c if isvalid(c) else c for c in re.findall('(?<=\[\[)[\w\W]+(?=\]\])', i)]) for i in tests]
将函数与
一起使用时排除
:
import re
excludes = ['Special:MyLanguage', 'Category:', 'File:', 'Image:']
s = "[[Special:MyLanguage/text]]\n[[File:text]]\n[[Image:text]]\n[[Category:text]]\n[[Text and ]]"
def analyze(match):
for exclude in excludes:
if exclude in match.group(1):
return '[[{}]]'.format(match.group(1))
return '[[Special:MyLanguage/{}]]'.format(match.group(1))
rx = re.compile(r'\[\[(.*?)\]\]')
s = rx.sub(analyze, s)
print(s)
这就产生了
[[Special:MyLanguage/text]]
[[File:text]]
[[Image:text]]
[[Category:text]]
[[Special:MyLanguage/Text and ]]
仅供参考,Python
re
不支持\G
,替换的反向引用语法是\n
或\G
。我建议将*?
编辑为[^\]]*
使正则表达式尽可能安全。尽管OP dodn没有明确提到它,但他们正在编辑wikilinks,内容中不应该有括号(除非它是递归的,这是不可能的,但上面的正则表达式不会检查匹配的递归括号。)@Graham如果[…]中没有]
,是的,[^]]*
效率更高。如果右侧分隔符是多字符字符串,而没有提供具体细节,我会使用延迟点匹配模式。
[[Special:MyLanguage/text]]
[[File:text]]
[[Image:text]]
[[Category:text]]
[[Special:MyLanguage/Text and ]]