用于根据长度过滤单词或排除 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|$)).*$
选项 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
所以非正则表达式解决方案只需要一半的时间。
我一直在努力解决这个问题,但由于我是正则表达式的新手,所以一直没能解决。我需要 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|$)).*$
选项 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
所以非正则表达式解决方案只需要一半的时间。