Replacing a variable length with `re.sub ()`

I would like to replace all occurrences of 3 or more "=" with an equal number "-".

def f(a, b):
    '''
    Example
    =======
    >>> from x import y
    '''
    return a == b

becomes

def f(a, b):
    '''
    Example
    -------
    >>> from x import y
    '''
    return a == b        # don't touch

My working but hacked solution is to pass the lambda to replfrom re.sub(), which captures the length of each match:

>>> import re

>>> s = """
... def f(a, b):
...     '''
...     Example
...     =======
...     >>> from x import y
...     '''
...     return a == b"""

>>> eq = r'(={3,})'
>>> print(re.sub(eq, lambda x: '-' * (x.end() - x.start()), s))

def f(a, b):
    '''
    Example
    -------
    >>> from x import y
    '''
    return a == b

Can I do this without having to pass a function to re.sub()?

My thinking would be what I need r'(=){3,}'(a variable-length capture group), but I think it re.sub(r'(=){3,}', '-', s)has a problem with greed.

Can I change the regex expression eqabove so that lambda is not needed?

+4
source share
4 answers

re.sub, , , '\n'.

print(re.sub('=(?=={2}|=?\n)', '-',  s))
def f(a, b):
    '''
    Example
    -------
    >>> from x import y
    '''
    return a == b


" , ".

=        # equal sign if
(?=={2}  # lookahead
|        # regex OR
=?       # optional equal sign
\n       # newline
)
+2

lookahead/lookbehind char:

>>> re.sub("(=(?===)|(?<===)=|(?<==)=(?==))", "-", "=== == ======= asdlkfj")
... '--- == ------- asdlkfj'
+3

, .

re.sub , , . , , re.sub(r'(=){3,}', '-', s), - , =.

>>> re.sub(r'(=){3,}', '-', '=== ===')
'- -'

, , , =, 3. , , , 3 = ={3,}. lookarounds :

(?<===)=|(?<==)=(?==)|=(?===)

, :

>>> re.sub(r'(?<===)=|(?<==)=(?==)|=(?===)', '-', '= == === ======')
'= == --- ------'

, lambda.

+2

regex, :

regex.sub(r'\G(?!\A)=|=(?===)', '-', s)
  • \G - .
  • (?!\A) .

The second branch =(?===)succeeds when =two others follow =. Then, in the following matches, the first branch \G(?!\A)=is used until there are no more consecutive ones =.

demo

+2
source

Source: https://habr.com/ru/post/1695284/


All Articles