仅当两个字符串不存在且其他两个字符串存在时,我才需要一个 python re 来匹配
Posted
技术标签:
【中文标题】仅当两个字符串不存在且其他两个字符串存在时,我才需要一个 python re 来匹配【英文标题】:I need a python re to match only if two strings are absent and two other strings are present 【发布时间】:2022-01-07 18:01:21 【问题描述】:使用 python 3.9.5,我有这个字符串
>>> t
' LICENSE INVALID\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n LICENSE INVALID\n Module AMS version2020.103\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n Module AMS version2020.103\nLICENSE INVALID\nLICENSE INVALID'
如果找到字符串“许可证无效”或“许可证不包括”之一,我想要一个返回 None 的 re;并且,如果这些字符串都不存在并且 both 字符串 '2020.103' 和 'NORMAL TERMINATION' 都存在,那么我才希望它返回匹配项。 (如果没有任何匹配项,也返回 None 。)到目前为止我有
>>> p=re.compile(r'^(?!.*LICENSE INVALID|license does not include).*(?:2020.103|NORMAL TERMINATION).*')
>>> print(p.search(s))
<re.Match object; span=(0, 8), match='2020.103'>
这是第一部分:如果“许可无效”或“许可不包括”在文本中,则返回 None。但是,我相信它正在对后两个字符串进行排他的“或”匹配。我希望它做一个“和”。当我不希望它不匹配时,它与上面匹配。我正在匹配的输出可能包含“2020.103”,无论是在失败(当我不希望我的 re 找到匹配时)还是成功(当我希望我的 re 找到匹配时)。我需要为此使用 re 以使其与我正在使用的其他人的代码相匹配。总结一下:只有当 '2020.103' 和 'NORMAL TERMINATION' 都找到了,并且没有找到 'LICENSE INVALID' 和 'license does not include' 时,才不返回 None。
【问题讨论】:
【参考方案1】:我可能会在这里避免使用正则表达式,而是使用基本字符串函数:
inp = [' LICENSE INVALID\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n LICENSE INVALID\n Module AMS version2020.103\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n Module AMS version2020.103\nLICENSE INVALID\nLICENSE INVALID', 'Hello 2020.103 is NORMAL TERMINATION']
for x in inp:
if "LICENSE INVALID" not in x and "license does not include" not in x and "2020.103" in x and "NORMAL TERMINATION" in x:
print("MATCH: " + x)
else:
print("NO MATCH: " + x)
只有列表中的第二个样本输入匹配。
【讨论】:
【参考方案2】:使用正则表达式,请您尝试一下:
p = re.compile(r'^(?!.*(?:LICENSE INVALID|license does not include)).*(?=.*2020.103)(?=.*NORMAL TERMINATION)')
如果 '2020.103' 和 'NORMAL TERMINATION' 都找到了,并且没有找到 'LICENSE INVALID' 和 'license does not include' 中的任何一个,它应该匹配。
【讨论】:
【参考方案3】:让我们明确要求:
“如果找到字符串 'LICENSE INVALID' 或 'license does not include' 之一,则返回 None”表示如果两个字符串中的任何一个出现在细绳。当我们使用负前瞻(?!.*pattern1)
,或者我们有两种模式时,我们使用 (?!.*pattern1)(?!.*pattern2)
或 (?!.*(?:pattern1|pattern2))
等等。
"字符串 '2020.103' 和 'NORMAL TERMINATION' 都存在,只有这样我才希望它返回一个匹配项。(如果没有任何匹配项,也返回一个 None。) " 表示你需要确保一个字符串在字符串中包含两个任意顺序的模式,这就是我们使用^(?=.*pattern1)(?=.*pattern2)
时的情况。
此外,您注意到上述模式中的.
。在 Python re
中,点默认不匹配换行符,您需要使用re.S
或re.DOTALL
标志(或在模式开始处添加(?s)
以重新定义.
中的行为整个正则表达式,或使用(?s:.)
而不是.
。
所以,让我们结合要求 - 将包含两个模式的字符串以任意顺序匹配但不包含一个或另一个模式 - 成一个正则表达式:
p=re.compile(r'^(?!.*\b(?:LICENSE INVALID|license does not include)\b)(?=.*(?<!\d)2020\.103(?!\d))(?=.*\bNORMAL TERMINATION\b).*', re.S)
详情:
^
- 字符串开头
(?!.*\b(?:LICENSE INVALID|license does not include)\b)
- 如果在零个或多个字符之后的任何位置有 LICENSE INVALID
或 license does not include
作为整个单词,则匹配失败,尽可能多
(?=.*(?<!\d)2020\.103(?!\d))
- 正向前瞻要求 2020.103
在零个或多个字符之后的任何位置都不能紧接在前面也不能跟在数字后面,尽可能多
(?=.*\bNORMAL TERMINATION\b)
- 正向前瞻要求在零个或多个字符后的任意位置使用 NORMAL TERMINATION
整个单词,尽可能多
.*
- 字符串的其余部分。如果您需要布尔结果,则不需要。
见Python demo:
import re
s = ' LICENSE INVALID\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n LICENSE INVALID\n Module AMS version2020.103\n Your license does not include module AMS version 2020.103 on this machine.\n Module AMS\n Module AMS version2020.103\nLICENSE INVALID\nLICENSE INVALID'
p=re.compile(r'^(?!.*\b(?:LICENSE INVALID|license does not include)\b)(?=.*(?<!\d)2020\.103(?!\d))(?=.*\bNORMAL TERMINATION\b).*', re.S)
print(p.search(s)) # NO MATCH, there is "LICENSE INVALID" and even "license does not include", there is no expected "NORMAL TERMINATION", although there is "2020.103"
print(p.search('NORMAL TERMINATION\nBlah-blah\n2020.103 code')) # MATCH, there are no "LICENSE INVALID" and "license does not include", there is "NORMAL TERMINATION" and "2020.103"
print(p.search('NORMAL TERMINATION\nBlah-blah\n2020.1030 code')) # NO MATCH, same as above but "2020.1030" is not "2020.103"
【讨论】:
以上是关于仅当两个字符串不存在且其他两个字符串存在时,我才需要一个 python re 来匹配的主要内容,如果未能解决你的问题,请参考以下文章
仅当找到第 1 组时,来自两个组的 Redshift SQL 汇总量