Python 正则表达式查找括号内的所有内容,并预先加上前缀

Python Regex to find everything within parenthesis, with a prefix beforehand

这似乎是一个相当简单的问题,但我无法让它工作。

我有一个文本文件,其中包含 JSON 之类的数据,但是还有几行,阻止它成为有效的 JSON,我需要删除这些。这听起来很简单,甚至更简单,因为有效的 JSON 字符串(我可以稍后解析)始终包含在以下容器中:

xyz()

因此,例如,数据集将类似于:

abcdefg
xyz({"id_value": 123, "text_value": "efg"})

abcdefg
xyz({"id_value": 124, "text_value": "hij"})

每个单独的 JSON 字符串总是以 abcdefg 为前缀,然后是 xyz( 并且后面总是有一个右括号。所以格式是一致的。

我正在尝试以下操作:

re.findall(r'xyz\(.*?\)', text_file)

然而,尽管尝试了这种变化(例如使用 re.search、尝试 \w+ 等),但似乎没有任何效果(我的意思是 returns 一个空列表)。

如果我只是尝试执行以下操作:

re.findall(r'xyz\(

然后returns:

['xyz(', 'xyz(']

符合预期。

所以问题似乎与括号中的字符串有关,但我无法弄清楚问题出在哪里,因为这里的其他示例表明我的代码是正确的(这不可能,因为它不正确'没用)!

我认为它非常简单,但我有点卡住了!

你可以通过运行 pip install regex(或pip3 install regex)安装PyPi regex模块,然后使用这个库来匹配xyz(和下一个配对 ) 字符使用:

import regex 
#...
output = [x.group() for x in regex.finditer(r'xyz(\((?:[^()]++|(?1))*\))', text_file)

当在正则表达式中定义捕获组时仅返回捕获的子字符串时,使用列表理解来避免 regex.findall 的问题(这里,括号周围的捕获组是必需的,因为它是递归的在模式中有一个 (?1) 子例程。

图案详情:

  • xyz - xyz 文字
  • (\((?:[^()]++|(?1))*\)) - 第 1 组:
    • \( - 一个 ( 字符
    • (?:[^()]++|(?1))* - 除了 () 之外的一个或多个字符的零次或多次重复,或者子例程重复(递归)整个第 1 组模式
    • \) - ) 个字符。