Python正则表达式如果是group-match,那么put-different-character

时间:2012-09-05 17:22:22

标签: python regex

我希望改变以下内容:

  

"一些文字 http://one.two.three.source.com 更多文字。更多文字   更多文字 http://source.com 更多文字。更多文字    http://one.source.com 更多文字更多文字。更多文字 http://one.two.source.com 更多文字更多文字"

对此:

  

"一些文字 http://one_two_three.target.com 更多文字更多文字   更多文字 http://target.com 更多文字更多文字    http://one.target.com 更多文字更多文字更多文字 http://one_two.target.com 更多文字更多文字"

我希望改变'。'将每个子域名分隔为“' _'在一大块文本中,问题是我想让它以是否存在子域为条件。 我无法预测文本的其余部分,只需要为url模式进行转换。

这是我到目前为止所做的:

src = 'source.com'
dst = 'target.com'
reMatch = r'http(?P<a>s?):(?P<b>\\?)/(?P<c>\\?)/(?P<d>([^.:/]+\.)?)(?P<e>([^.:/]+\.)?)(?P<f>([^.:/]+\.)?)' + src
p = re.compile(reMatch, re.IGNORECASE)
reReplace = r'http\g<a>:\g<b>/\g<c>/\g<d>\g<e>\g<f>' + dst
p.sub(reReplace, content)

它只取代了'source.com&#39;与&#39; target.com&#39;并复制子域名(最多3个),但不要替换&#39;。&#39;用&#39; _&#39;在子域之间。

4 个答案:

答案 0 :(得分:1)

我构建了一个函数,根据您的输入实现所需的输出:

def special_replace(s):
    p=re.compile(r"(http://.*?)(\.?source\.com)")
    spl=p.split(s)
    newtext=[]
    for text in spl:
        if text.startswith("http://"):
            text=text.replace(".","_")
        elif text.endswith("source.com"):
            text=text.replace("source.com", "target.com")
        newtext.append(text)
    return "".join(newtext)

它不是那么优雅但它达到了你的目标:)。

答案 1 :(得分:0)

这是halex答案的变体。来自itertools recipesgrouper可用于处理re.split的结果。

def special_replace(s):
    spl = re.split(r"(http://.*?)(\.?source\.com)", s)
    return "".join(
        itertools.chain(*((
                  text,
                  part1.replace(".", "_"),
                  part2.replace("source.com", "target.com"))
              for text, part1, part2 in grouper(3, spl, ""))))

答案 2 :(得分:0)

难点在于您对匹配的表达式应用了两个不同的更改。我建议你在整个文件中应用其中一个更改,然后匹配这个新表达式,以便使用捕获的组重建它:

text = re.sub(r'(http://[^ ]*)source\.com\b', r'\1target.com', text)
pattern = re.compile(r'(http://[^ ]+)\.([^ ]*target.com)\b')

while (pattern.search(text)):
   text = pattern.sub(r'\1_\2', text)

答案 3 :(得分:0)

以下是使用函数作为替换的地方:

def replace_dots(source):
    from_dot_com = 'source.com'
    to_dot_com = 'target.com'

    pat = re.compile(r'(https?://)(\S*?)(\.?)'
                     + re.escape(from_dot_com),
                        re.IGNORECASE)

    def my_fun(match):
        return (match.group(1) 
            + match.group(2).replace('.', '_') # <--
            + match.group(3) + to_dot_com)

    result = pat.sub(my_fun, source)

    return result