regex 正在从匹配对象获取匹配的模式

fnvucqvd  于 2023-01-14  发布在  其他
关注(0)|答案(2)|浏览(114)

我在使用Python正则表达式,我试图从match对象中获得模式匹配,而不是文本匹配。
我有一些模式要替换,我这样做:

import re

patterns = {
    r'^[ |\n]+': '',
    r'[ |\n]+$': '',
    r'[ |\n]+': ' '
}

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join(patterns.keys()),
              lambda match: patterns[ match.group(0) ],
              text)

但这是一个错误的解决方案,因为match.group(0)返回匹配的文本,所以它们都不等于模式dict的任何键。
我尝试了match.pattern,但得到了一个异常,并尝试了match.re,但这给出了所有re.compile对象,其针对此问题的模式是'^[ |\n]+|[ |\n]+$|[ |\n]+'

**编辑:**基于Barmar解决方案,我得到了以下结果:

import re

patterns = [
    (r'^[ |\n]+', ''),
    (r'[ |\n]+$', ''),
    (r'[ |\n]+', ' ')
]

def getreplacement(match):
    for i, group in enumerate(match.groups()):
        if group:
            return patterns[ i ][ 1 ]

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join('(' + p[ 0 ] + ')' for p in patterns), getreplacement, text)
print(text)

但仍然不是一种总是从匹配组中获得模式的方法。

vngu2lb8

vngu2lb81#

我不认为有一种方法可以直接找出哪个选项匹配。
使用列表而不是字典,并将每个模式放入一个捕获组中。然后可以查看匹配的捕获组,并将其用作索引以获取相应的替换。
请注意,如果模式中有任何捕获组,这将不起作用。如果需要组,请确保它们是非捕获组。

import re

patterns = [
    (r'^[ |\n]+', ''),
    (r'[ |\n]+$', ''),
    (r'[ |\n]+', ' ')
]

def getreplacement(match):
    for i in range(1, match.groups):
        if match.group(i):
            return patterns[i-1][1]

text = ' Hello there,  I\n need your help  here    plase :) '
text = re.sub('|'.join('(' + p[0] + ')' for p in patterns), getreplacement, text)
kb5ga3dv

kb5ga3dv2#

如果我理解正确的话,您需要去掉前导空格和尾随空格,并将中间的空格减少到只有一个。
首先,您的代码可能有一个bug:[ |\n]将匹配空格(``)、竖线(|)或换行符。您可能不希望匹配竖线,但可能希望匹配所有空白字符,例如制表符(\t)。
二、造型:保持你的行在80个字符以内,并且在括号中的索引周围没有空格。
第三,使用str.strip可以简单地删除前导和尾随空格,现在唯一需要替换的是两个或更多空格的序列,这很容易与\s{2,}匹配(\s =“whitespace”,{2,} =“two or more”)。
下面是代码的修改:

import re

patterns = [
    (r"^[ |\n]+", ""),
    (r"[ |\n]+$", ""),
    (r"[ |\n]+", " "),
]

def get_replacement(m: re.Match) -> str:
    return next(
        patterns[i][1]
        for i, group in enumerate(m.groups())
        if group is not None
    )

text = (
    "\n"
    " \t   Hello there,  I\n need your help  here    plase :) \t  \n"
    " \t   Hello there,  I\n need your help  here    plase :)  \t "
    "\n"
)
result1 = re.sub(
    "|".join(f"({p})" for p, _ in patterns),
    get_replacement,
    text,
)
result2 = re.sub(r"[ \n]{2,}", " ", text.strip())
result3 = re.sub(r"\s{2,}", " ", text.strip())
print(repr(result1))
print(repr(result2))
print(repr(result3))

相关问题