考虑来自CFEngine的这段代码:
"test"
slist => { "this",
"that" },
"test2"
slist => { "another,
"another"
},
"test3"
string => "This one";
"test4"
slist => { "finally",
"this" }
我想要Python中的代码,该代码将获取标识符(“ test1”,“ test2”等)以及{}
之间的内容。
我是这样来的:
re.findall(r'^\s*?\"(.*?)\".*?\{(.*?)\}.*?',filestring,re.MULTILINE | re.DOTALL)
效果很好,除了最终得到'finally'.'this'
作为"test3"
的匹配项,而不是"test4"
的匹配项。
我试图通过这种方式与松散的人一起工作:
re.findall(r'^\s*?\"(.*?)\".*?\{(?!<.*?\".*?)(.*?)\}.*?',filestring,re.MULTILINE | re.DOTALL)
希望(?!<.*?\".*?)
将排除以前带有引号字符的匹配项,但是它不起作用,我一直得到相同的结果。
有人可以帮助我实现这一目标吗?我知道我可以进行其他测试,例如测试下一行是否包含slist
,但是我想避免这样做,因为有时代码具有注释,如
"test4"
# some comment
slist => { "something"}
我唯一确定的将标识符与它们的内容匹配的方法是排除没有{}
的其他赋值的结果。因此,我正在考虑使用"
符号来排除匹配项,但是它并没有达到我的预期。
有人可以在这里说些什么吗?
答案 0 :(得分:1)
您可以使用此正则表达式:
r'(?s)^("[^"]+").*?=> ("[^"]*"|{[^}]*})'
(?s)
:启用DOTALL修饰符。("[^"]+")
:匹配并捕获第一个带引号的字符串("[^"]*"|{[^}]*})
:匹配第二组,可以是带引号的字符串或{...}
答案 1 :(得分:1)
尝试一下^\s*?\"(.*?)\".*?(?:".*?"|\{(.*?)\})
这与第一组""
之间的文本匹配,然后查找""
或{}
之间的某项,如果介于{}
之间,则捕获该文本。
然后,您需要检查代码中是否设置了第二个捕获组。
答案 2 :(得分:0)
在@anubhava和@JGNI的帮助下,我明白了:
re.findall(r'(?s)^\s*?\"(.*?)\".*?=> .*?(\".*?\"|\{.*?\})',filestring,re.MULTILINE)
这样,我也可以捕获不需要的东西,但是很容易将其丢弃。