如何使用'?'在python中提取两个匹配模式之间的可选子字符串?

2024-03-29 02:22:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我是answering this question.考虑一下这个字符串

str1 = '{"show permission allowed to 16": "show permission to 16\\nSchool permissions from group 17:student to group 16:teacher:\\n\\tAllow ALL-00\\nSchool permissions from group 18:library to group 16(Temp):teacher:\\n\\tNo Allow ALL-00\\nSchool permissions from group 20:Gym to group 16:teacher:\\n\\tCheck ALL-00\\nRTYAHY: FALSE\\nRTYAHY: FALSE\\n\\n#"}'

假设我想提取每个子串from group后面的数字,以及\\t后面有最小匹配字符串的子串。你知道吗

我用下面的正则表达式

import re
res = re.findall(r'from group (\d+).*?\\t(.*? ALL-..)', str1)

输出为:

[('17', 'Allow ALL-00'), ('18', 'No Allow ALL-00'), ('20', 'Check ALL-00')]

现在在我提取的每个子串(数字和\t后面的子串)之间可能有一个可选的子串,它的值是我要提取的Temp(如果存在)。例如,在18No Allow ALL-00之间,有一个子串Temp我想提取。你知道吗

我尝试使用?如下:

res = re.findall(r'from group (\d+).*?(Temp)?.*?\\t(.*? ALL-..)', str1)

但是结果元组中相应的第二个元素总是空的:

[('17', '', 'Allow ALL-00'), ('18', '', 'No Allow ALL-00'), ('20', '', 'Check ALL-00')]

当我期待着这样的事情时:

[('17', '', 'Allow ALL-00'), ('18', 'Temp', 'No Allow ALL-00'), ('20', '', 'Check ALL-00')]

在这种情况下如何提取子字符串?我犯了什么错误?你知道吗

还有一个问题:假设我希望我的结果列表没有这个元素(包含Temp的元素):我应该只使用[^]然后使用相应的匹配模式吗?你知道吗


Tags: tono字符串fromrepermissionscheckgroup
1条回答
网友
1楼 · 发布于 2024-03-29 02:22:00

它没有捕获Temp的原因是您将它设置为可选的,因为.*?会使用它,并且Temp不会在可选组中捕获。你知道吗

为了解决这个问题,您可以使用否定的前瞻来拒绝捕获Temp,除了使用这个正则表达式的任何其他字符

from group (\d+)(?:(?!Temp).)*?(Temp)?(?:(?!Temp).)*?\\t(.*? ALL-..)
                   ^^^^^^^^^ This rejects Temp getting captured except any other character

正则表达式解释:

  • from group-此文本的文本匹配
  • (?:(?!Temp).)*?-?:表示它是一个非捕获组,默认情况下是一个捕获组,这意味着在看到Temp字符串和*表示捕获零个或多个字符时,捕获任何东西都不会停止。所以它捕获任何不包含Temp?的字符串意味着尽可能少
  • (Temp)?-如果存在,可以选择捕获Temp
  • (?:(?!Temp).)*?-再次捕获任何字符零次或多次,除了Temp,如上所述
  • \\t-从字面上理解这一点
  • (.*? ALL-..)-捕获尽可能少的任何字符,后跟空格,后跟文字ALL-,后跟任意两个字符

希望这能澄清正则表达式。如果您有任何疑问,请告诉我。你知道吗

Demo

Python代码示例

import re

s = '{"show permission allowed to 16": "show permission to 16\\nSchool permissions from group 17:student to group 16:teacher:\\n\\tAllow ALL-00\\nSchool permissions from group 18:library to group 16(Temp):teacher:\\n\\tNo Allow ALL-00\\nSchool permissions from group 20:Gym to group 16:teacher:\\n\\tCheck ALL-00\\nRTYAHY: FALSE\\nRTYAHY: FALSE\\n\\n#"}'

arr = re.findall(r'from group (\d+)(?:(?!Temp).)*?(Temp)?(?:(?!Temp).)*?\\t(.*? ALL-..)',s)
print(arr)

指纹

[('17', '', 'Allow ALL-00'), ('18', 'Temp', 'No Allow ALL-00'), ('20', '', 'Check ALL-00')]

编辑:仅列出不包含Temp

您需要使用这个正则表达式来避免匹配中包含Temp字符串的子字符串

from group (\d+)(?:(?!Temp).)*\\t(.*? ALL-..)

Demo

Python代码示例

import re

str1 = '{"show permission allowed to 16": "show permission to 16\\nSchool permissions from group 17:student to group 16:teacher:\\n\\tAllow ALL-00\\nSchool permissions from group 18:library to group 16(Temp):teacher:\\n\\tNo Allow ALL-00\\nSchool permissions from group 20:Gym to group 16:teacher:\\n\\tCheck ALL-00\\nRTYAHY: FALSE\\nRTYAHY: FALSE\\n\\n#"}'

arr = re.findall(r'from group (\d+)(?:(?!Temp).)*\\t(.*? ALL-..)',str1)
print(arr)

指纹

[('17', 'Allow ALL-00'), ('20', 'Check ALL-00')]

它不包含具有Temp的元组

相关问题 更多 >