在正则表达式匹配中插入一个字符串

时间:2018-05-14 19:22:01

标签: python regex string match

我需要将字符串Special:MyLanguage/插入[[ACBDEF]]之类的字符串中,使其成为[[Special:MyLanguage/ABCDEF]]

问题是,我需要排除某些不应该插入Special:MyLanguage/的匹配项:

  • 已包含Special:MyLanguage/
  • 的字符串
  • Category:
  • File:,或
  • Image:

不幸的是,将\[\[替换为\[\[Special:MyLanguage/并不起作用。此外,替换\[\[[^(Special:MyLanguage|File:|Image:|Category:)]不起作用,因为它包含第一个字符(匹配将是[[A)。我已经阅读了很多教程,尝试了$1\G这类事情,但我仍然在摸不着头脑。

4 个答案:

答案 0 :(得分:1)

您可以使用否定前瞻来确保在[[之后不会发生这些子字符串:

(\[\[)(?!Special:MyLanguage/|File:|Image:|Category:)(.*?]])

并替换为\1Special:MyLanguage/\2。请参阅regex demo

<强>详情

  • (\[\[) - 第1组:[[ substring
  • (?!Special:MyLanguage/|File:|Image:|Category:) - [[无法跟随更改组中列出的任何子字符串
  • (.*?]]) - 第2组:除了换行符之外的任何0 +字符,尽可能少,然后是]]

Python demo

import re
rx = r"(\[\[)(?!Special:MyLanguage/|File:|Image:|Category:)(.*?]])"
s = "[[Special:MyLanguage/text]]\n[[File:text]]\n[[Image:text]]\n[[Category:text]]\n[[Text and ]]"
res = re.sub(rx, r"\1Special:MyLanguage/\2", s)
print(res)

输出:

[[Special:MyLanguage/text]]
[[File:text]]
[[Image:text]]
[[Category:text]]
[[Special:MyLanguage/Text and ]]

答案 1 :(得分:0)

如果你不想搞乱正则表达式,这是一个更简单的解决方案。

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:]

如果他们都完全遵循您提供的模式:[[某事]],他们将按照您的问题插入。

对于这样一个简单的案例,我发现regExes过于复杂,尤其是在使用前瞻,外观和使用捕获组时。尽可能保持简单,保存算法的复杂性,以便在需要时,只需说出来。

答案 2 :(得分:0)

您可以使用re.subre.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]

输出:

['[[Special:MyLanguage/ACBDEF]]', '[[Special:MyLanguage/ACBDEF]]', '[[Category:ACBDEF]]', '[[File:ACBDEF]]', '[[Special:MyLanguage/OneLasttest]]']

答案 3 :(得分:0)

使用excludes的函数:

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 ]]