python - 在 Python 中用任意值替换命名的捕获组

标签 python regex python-2.7

我需要用某个任意值替换正则表达式捕获组中的值;我查看了 re.sub,但它似乎以不同的方式工作。

我有这样一个字符串:

s = 'monthday=1, month=5, year=2018'

我有一个正则表达式将其与捕获的组匹配,如下所示:

regex = re.compile('monthday=(?P<d>\d{1,2}), month=(?P<m>\d{1,2}), year=(?P<Y>20\d{2})')

现在我想用 aaa 替换名为 d 的组,用 bbb 替换名为 m 的组和使用 ccc 命名为 Y 的组,如以下示例所示:

'monthday=aaa, month=bbb, year=ccc'

基本上我想保留所有不匹配的字符串并用一些任意值替换匹配组。

有没有办法达到预期的效果?

注意事项

这只是一个例子,我可以有其他具有不同结构但同名捕获组的输入正则表达式......

更新

因为似乎大多数人都在关注示例数据,所以我添加了另一个示例,假设我有其他输入数据和正则表达式:

input = '2018-12-12'
regex = '((?P<Y>20\d{2})-(?P<m>[0-1]?\d)-(?P<d>\d{2}))'

如您所见,我仍然拥有相同数量的捕获组 (3),并且它们的命名方式相同,但结构完全不同......不过,我需要的是像以前一样用一些任意的替换捕获组文本:

'ccc-bbb-aaa'

将名为 Y 的捕获组替换为 ccc,将名为 m 的捕获组替换为 bbb 和名为 d 的捕获组 aaa.

在这种情况下,正则表达式不是完成这项工作的最佳工具,我愿意接受其他一些可以实现我的目标的建议。

最佳答案

这是对正则表达式的完全反向使用。捕获组的目的是保存您想要保留的文本,而不是您想要替换的文本。

由于您以错误的方式编写了正则表达式,因此您必须手动完成大部分替换操作:

"""
Replaces the text captured by named groups.
"""
def replace_groups(pattern, string, replacements):
    pattern = re.compile(pattern)
    # create a dict of {group_index: group_name} for use later
    groupnames = {index: name for name, index in pattern.groupindex.items()}

    def repl(match):
        # we have to split the matched text into chunks we want to keep and
        # chunks we want to replace
        # captured text will be replaced. uncaptured text will be kept.
        text = match.group()
        chunks = []
        lastindex = 0
        for i in range(1, pattern.groups+1):
            groupname = groupnames.get(i)
            if groupname not in replacements:
                continue

            # keep the text between this match and the last
            chunks.append(text[lastindex:match.start(i)])
            # then instead of the captured text, insert the replacement text for this group
            chunks.append(replacements[groupname])
            lastindex = match.end(i)
        chunks.append(text[lastindex:])
        # join all the junks to obtain the final string with replacements
        return ''.join(chunks)

    # for each occurence call our custom replacement function
    return re.sub(pattern, repl, string)
>>> replace_groups(pattern, s, {'d': 'aaa', 'm': 'bbb', 'Y': 'ccc'})
'monthday=aaa, month=bbb, year=ccc'

关于python - 在 Python 中用任意值替换命名的捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47396866/

相关文章:

regex - 使用正则表达式检查字符串是否以数字开头

php - 是否有可以清理内容的 PHP 类?

python - 使用 PPID 创建文件

python - 如何在 python 中生成所有可能的字符串?

python - SQLAlchemy 过滤时出错

python - Scrapy:ImportError:无法导入名称设置

python - 为什么tf.layers.batch_normalization的参数 'scale'在下一层是relu时被禁用?

python - sklearn countvectorizer中的fit_transform和transform有什么区别?

javascript - 将包含时间的字符串转换为 24 小时时间我可以用 - jQuery 做数学

python - 如何读取python字节码?