首页 > 解决方案 > 如何有效地传递或忽略一些由 python 正则表达式解析的标记?

问题描述

我将一个函数应用于令牌列表,如下所示:

def replace(e): 
    return e


def foo(a_string):
    l = []
    for e in a_string.split():
        l.append(replace(e.lower()))
    return ' '.join(l)

使用字符串:

s = 'hi how are you today 23:i ok im good 1:i'

函数 foo 更正s. 但是,有些情况我想忽略,例如 12:i 或 2:i。我怎样才能应用foo到所有没有被正则表达式解析的令牌:\d{2}\b:i\b|\d{1}\b:i\b?也就是说,我希望foo忽略所有带有23:ior 01:eor形式的标记1:i。我在考虑一个正则表达式,但是,也许有更好的方法来做到这一点。

预期的输出将是:

'hi how are you today 23:i ok im good 1:e'

换句话说,该函数foo忽略形式为nn:ior的标记n:i,其中n是一个数字。

标签: pythonregexpython-3.x

解决方案


您可以使用

import re

def replace(e): 
    return e

s = 'hi how are you today 23:i ok im good 1:e'
rx = r'(?<!\S)(\d{1,2}:[ie])(?!\S)|\S+'
print(re.sub(rx, lambda x: x.group(1) if x.group(1) else replace(x.group().lower()), s))

请参阅在线 Python 演示正则表达式演示

模式(?<!\S)(\d{1,2}:[ie])(?!\S)|\S+匹配

  • (?<!\S)(\d{1,2}:[ie])(?!\S)- 1 或 2 位数字,:ie用空格或字符串开始/结束位置括起来(将子字符串捕获到第 1 组)
  • |- 或者
  • \S+- 1+ 非空白字符。

一旦第 1 组匹配,其值将按原样粘贴回来,否则,将小写匹配传递给replace方法并返回结果。

另一种正则表达式方法:

rx = r'(?<!\S)(?!\d{1,2}:[ie](?!\S))\S+'
s = re.sub(rx, lambda x: replace(x.group().lower()), s)

查看另一个 Python 演示和一个正则表达式演示

细节

  • (?<!\S)- 检查紧靠左边的字符是否为空格或断言字符串的起始位置
  • (?!\d{1,2}:[ie](?!\S))- 如果紧挨当前位置的右侧有 1 或 2 位数字、:ie,则匹配失败的负前瞻,然后应跟随空格或字符串结尾
  • \S+- 1+ 非空白字符。

推荐阅读