用于识别组的正则表达式

Regular expression to identify groups

content = "[row1|col1]:{value:{{calculate}}<<report_1>>[Row2|col2];format:float;} [hiddenr0120a|c0012]:{format:float;}"
regex = re.compile(r"(\[.*?\]).*?\{(.*?)\}")
entries = regex.findall(content)
#Output
[('[row1|col1]', 'value:{{calculate'), ('[Row2|col2]', 'format:float;')]
#Expected Output
[("[row1|col]", "{value:{{calculate}}<<report_1>>[Row2|col2];format: float;}"), ("[hiddenr0120a|c0012]", "{format:float;}")]

我试过正则表达式“([.?]).?{(.*?)}”,它实际上在“}”的第一个实例处结束,所以它第一种情况失败。

你可能会用到

(\[[^\[\]\r\n]*\]):({.*?})(?: (?=\[)|$)

部分

  • ( 捕获 组 1
    • \[[^\[\]\r\n]*\] 匹配从左方括号到右方括号
  • ) 关闭组 1
  • : 按字面匹配(或使用 .*? 匹配其他字符)
  • ( 捕获组 2
    • {.*?}{} 尽可能少地匹配
  • ) 关闭 组 2
  • (?:非捕获组 (?=[) 匹配一个 space 并断言右边的是 [
    • |
    • $ 断言字符串结束
  • )关闭非捕获组

Regex demo | Python demo

示例代码

import re
 
content = "[row1|col1]:{value:{{calculate}}<<report_1>>[Row2|col2];format:float;} [hiddenr0120a|c0012]:{format:float;}"
regex = re.compile(r"(\[[^\[\]\r\n]*\]):({.*?})(?: (?=\[)|$)")
entries = regex.findall(content)
print (entries)

输出

[('[row1|col1]', '{value:{{calculate}}<<report_1>>[Row2|col2];format:float;}'), ('[hiddenr0120a|c0012]', '{format:float;}')]

使用额外的捕获组,并像这样提取:

import re

text = "[row1|col1]:{value:{{calculate}}<<report_1>>[Row2|col2];format:float;} [hiddenr0120a|c0012]:{format:float;}"
pattern = r'(\[.*?\]).*?\{(.*?\})\s(\[.*\])\:(\{.*\})'
regex = re.compile(pattern)
entries = re.findall(regex, text)

for entry in entries[0]:
    print(entry)

返回:

[row1|col1]
value:{{calculate}}<<report_1>>[Row2|col2];format:float;}
[hiddenr0120a|c0012]
{format:float;}

如果第二组总是以;}结尾,那么正则表达式可能就这么简单
(\[.+?\]):(\{.*?;\})

import re
content = '''
[row1|col1]:{value:{{calculate}}<<report_1>>[Row2|col2];format:float;}
[hiddenr0120a|c0012]:{format:float;}
'''
r = re.compile(r'(\[.+?\]):(\{.*?;\})')
expected = [("[row1|col1]", "{value:{{calculate}}<<report_1>>[Row2|col2];format:float;}",),
            ("[hiddenr0120a|c0012]", "{format:float;}",),]
assert all(t == expected[i][j] for i, x in enumerate(r.findall(content)) for j, t in enumerate(x))

Demo.