用于根据长度过滤单词或排除 Python 中的单词的正则表达式

regex for filtering word based on length or by excluding a word in Python

我一直在努力解决这个问题,但由于我是正则表达式的新手,所以一直没能解决。我需要 select 某些 telnet 输出的正确行,如下所示:

systemstatus get resume    # line to exclude
systemstatus get idle      # line to filter
systemstatus get talking   # line to filter
systemstatus get ringing   # line to filter
systemstatus get outgoing  # line to filter
systemstatus get sleeping  # line to filter

如您所见,我需要排除带有简历的那个,select 所有其他的。所以我知道我可以按长度过滤,但我只知道如何按比某物大但不是很多长度的长度进行过滤。例如:"systemstatus get \w{7,}" 将排除 resume 行,但也会排除 idle 行。所以实际上我需要过滤长度为 4、7 和 8 的东西。

有人知道怎么做吗?

注意:由于 telnet 库,这必须在正则表达式中完成。

注2:由于是telnet,所以出现systemstatus get resume时我必须继续阅读(这就是我所说的"excluding"),而不是像出现[=16=时那样停下来] 进来。所以通过 "systemstatus get WHATEVER" 过滤然后排除 "resume" 会在 "resume" 进来时停止阅读。我正在使用 telnet lib 的 telnet.expect([], timeout)

使用零宽度负前瞻 ((?!resume(?:\s|$))) 以确保 resume 不会出现在 systemstatus get 之后:

^systemstatus get (?!resume(?:\s|$)).*$

Demo

选项 1
使用 re.MULTILINE 开关调用 re.findall

matches = re.findall(r"systemstatus get \b(?:\w{4}|\w{7,8})\b", t, re.M)

其中 returns 每个匹配字符串列表。

正则表达式详细信息

systemstatus get    # literals
\b                  # word boundary
(?:                 # non-capturing group
\w{4}               # find a word of size 4 
|                   # regex OR pipe
\w{7,8}             # find a word of size 7 or 8
)
\b

根据您的要求,我们在此处按字长进行匹配 -

I need something that filters lengths of 4, 7 and 8.


选项 2
将多行字符串拆分为单独的行,遍历每一行并在每一行上调用 re.match -

matches = []

for line in t.splitlines():
    if re.match(r"systemstatus get \b(?:\w{4}|\w{7,8})\b", line):
        matches.append(line)  

虽然正则表达式很强大,但这里并不真正需要它们,只是拆分、应用和组合:

text = """
systemstatus get resume    # line to exclude
systemstatus get idle      # line to filter
systemstatus get talking   # line to filter
systemstatus get ringing   # line to filter
systemstatus get outgoing  # line to filter
systemstatus get sleeping  # line to filter
"""

lines = "\n".join([line for line in text.split("\n") 
                  if line and not "resume" in line])
print(lines)

这会产生

systemstatus get idle      # line to filter
systemstatus get talking   # line to filter
systemstatus get ringing   # line to filter
systemstatus get outgoing  # line to filter
systemstatus get sleeping  # line to filter

除非您碰巧没有像 systemstatusresumesystem get idle 这样的文本(意思是 resume 没有任何单词边界),否则不需要正则表达式引擎的开销。


计时不同的方法(每个 100k)产生

print(timeit.timeit(noregex, number=10**5))
# 0.28622116599945 s

print(timeit.timeit(regex, number=10**5))
# 0.5753898609982571 s

所以非正则表达式解决方案只需要一半的时间