如果先前的比赛包含一个字符,则不匹配

时间:2018-09-04 10:16:30

标签: python regex

考虑来自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"}

我唯一确定的将标识符与它们的内容匹配的方法是排除没有{}的其他赋值的结果。因此,我正在考虑使用"符号来排除匹配项,但是它并没有达到我的预期。

有人可以在这里说些什么吗?

3 个答案:

答案 0 :(得分:1)

您可以使用此正则表达式:

r'(?s)^("[^"]+").*?=> ("[^"]*"|{[^}]*})'

RegEx Demo

  • (?s):启用DOTALL修饰符。
  • ("[^"]+"):匹配并捕获第一个带引号的字符串
  • ("[^"]*"|{[^}]*}):匹配第二组,可以是带引号的字符串或{...}

答案 1 :(得分:1)

尝试一下^\s*?\"(.*?)\".*?(?:".*?"|\{(.*?)\})

这与第一组""之间的文本匹配,然后查找""{}之间的某项,如果介于{}之间,则捕获该文本。

然后,您需要检查代码中是否设置了第二个捕获组。

答案 2 :(得分:0)

在@anubhava和@JGNI的帮助下,我明白了:

re.findall(r'(?s)^\s*?\"(.*?)\".*?=> .*?(\".*?\"|\{.*?\})',filestring,re.MULTILINE)

这样,我也可以捕获不需要的东西,但是很容易将其丢弃。