我是answering this questio n。考虑这个字符串
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
(如果存在)。例如,在18
和No 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
的元素):我应该只使用[^]
然后使用相应的匹配模式吗?
答案 0 :(得分:1)
不捕获Temp
的原因是因为.*?
使用了它,因此您将其设为可选,而Temp
未被捕获到您的可选组中。
要解决该问题,您可以使用否定前瞻来拒绝Temp
被捕获,但使用此正则表达式的其他字符除外。
from group (\d+)(?:(?!Temp).)*?(Temp)?(?:(?!Temp).)*?\\t(.*? ALL-..)
^^^^^^^^^ This rejects Temp getting captured except any other character
正则表达式说明:
from group
-此文本的字面匹配(?:(?!Temp).)*?
-?:
表示它是一个非捕获组,默认情况下是捕获组,这意味着捕获所有内容,但在看到Temp
字符串和{{1}时停止}表示捕获零个或多个字符。因此,这会捕获不包含*
的任何字符串,并且Temp
意味着尽可能少的?
-(可选)捕获(Temp)?
(如果存在)Temp
-再次捕获除(?:(?!Temp).)*?
之外的所有字符零次或多次Temp
-从字面上捕获\\t
-捕获的字符越少越好,后跟空格,然后是文字(.*? ALL-..)
,后跟任意两个字符希望这可以澄清正则表达式。如果您还有其他疑问,请告诉我。
示例Python代码,
ALL-
打印
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
示例Python代码,
from group (\d+)(?:(?!Temp).)*\\t(.*? ALL-..)
打印
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')]
的元组