Regex replace (in Python) - a simpler way?

前端 未结 4 467
广开言路
广开言路 2020-12-12 22:16

Any time I want to replace a piece of text that is part of a larger piece of text, I always have to do something like:

\"(?Psome_pattern)(?P<         


        
4条回答
  •  感情败类
    2020-12-12 22:40

    The short version is that you cannot use variable-width patterns in lookbehinds using Python's re module. There is no way to change this:

    >>> import re
    >>> re.sub("(?<=foo)bar(?=baz)", "quux", "foobarbaz")
    'fooquuxbaz'
    >>> re.sub("(?<=fo+)bar(?=baz)", "quux", "foobarbaz")
    
    Traceback (most recent call last):
      File "", line 1, in 
        re.sub("(?<=fo+)bar(?=baz)", "quux", string)
      File "C:\Development\Python25\lib\re.py", line 150, in sub
        return _compile(pattern, 0).sub(repl, string, count)
      File "C:\Development\Python25\lib\re.py", line 241, in _compile
        raise error, v # invalid expression
    error: look-behind requires fixed-width pattern
    

    This means that you'll need to work around it, the simplest solution being very similar to what you're doing now:

    >>> re.sub("(fo+)bar(?=baz)", "\\1quux", "foobarbaz")
    'fooquuxbaz'
    >>>
    >>> # If you need to turn this into a callable function:
    >>> def replace(start, replace, end, replacement, search):
            return re.sub("(" + re.escape(start) + ")" + re.escape(replace) + "(?=" + re.escape + ")", "\\1" + re.escape(replacement), search)
    

    This doesn't have the elegance of the lookbehind solution, but it's still a very clear, straightforward one-liner. And if you look at what an expert has to say on the matter (he's talking about JavaScript, which lacks lookbehinds entirely, but many of the principles are the same), you'll see that his simplest solution looks a lot like this one.

提交回复
热议问题