regex 正则表达式转换为python可接受的格式

yhived7q  于 2023-08-08  发布在  Python
关注(0)|答案(2)|浏览(76)

我发现这个正则表达式似乎适用于Java,但不适用于Python。在这里找到:Regex: Remove Commas within quotes

r"""(\G(?!^)|\"body\"\s*:\s*\")([^\",]*),"""

字符串
我在构建自己的正则表达式方面非常缺乏经验,需要帮助将其翻译为Python可接受的格式。我知道\G是问题所在,因为它在python中不存在(?)
我想用它来替换JSON文件中“body”键中的逗号,但我得到:
位置1处的错误转义\G

jum4pzuy

jum4pzuy1#

正确的解决方案

使用JSON模块解析JSON,修改结果对象,然后再次进行字符串化:

import json

json_str = '{"body": "a, b", "foo": "bar", "baz": "foo"}'
json_obj = json.loads(json_str)
def replace_commas_body(obj):
    if type(obj) == list:
        for elem in list:
            replace_commas_body(elem)
    elif type(obj) == dict:
        if "body" in obj:
            obj["body"] = obj["body"].replace(",", ";")
        for elem in obj.values():
            replace_commas_body(elem)
replace_commas_body(json_obj)
print(json.dumps(json_obj))

字符串
这将按预期打印{"body": "a; b", "foo": "bar", "baz": "foo"}

RegEx解决方案

为了好玩,我还写了一个RegEx解决方案。这样做很好,因为正则表达式足以标记JSON,并且这里所需的更改几乎可以在标记级别完成。
这种解决方案的(微小的)优点是它保留了JSON的“风格”(间距、键的顺序、使用的数字格式、转义的字符等)。
缺点是它的可读性较低/更难维护,灵活性也差得多:它不知道上下文。将此更改为例如。仅应用于还具有某些其他键或在某些其他对象内部的某些对象是不可能的。
为了简单起见,我决定根本不处理\uXXXX形式的Unicode转义序列,尽管这些ASCII码点理论上可以用这种方式编码;通常情况下,它不会,并且通过对字符串中的每个ASCII字符(字符body和逗号)使用(?:<character>|\\u<ASCII code>)来修复解决方案以正确处理它们是微不足道的。
下面是RegEx:(\"body\"\s*:\s*\")((?:[^\"\\]|\\.)*?)(\")
说明:

  • (\"body\"\s*:\s*\"):捕获"body" : "部分并保存;允许任意间距,就像JSON一样。
  • ((?:[^\"\\]|\\.)*?):捕获字符串的主体。允许零个或多个任意字符,但反斜杠或字符串引号除外,它们需要转义。
  • (\"):保留字符串的结束引号。我们也可以在lambda中硬编码它,但是如果你想在将来扩展它,这会更干净。

下面是相应的Python,以及一个小的测试用例:

import re

json_str = '{"body": "a, b", "foo": "bar", "baz": "foo"}'
print(re.sub(r"(\"body\"\s*:\s*\")((?:[^\"\\]|\\.)*?)(\")",
    lambda m: m.group(1) + m.group(2).replace(",", ";") + m.group(3),
    json_str))


在我的示例中,我将逗号(,)替换为分号(;)。你链接了一个关于 * 删除 * 逗号的问题,但提到了 * 替换 * 逗号(用什么?)在你的问题,所以我不确定。

rpppsulh

rpppsulh2#

您可以首先捕获 body 值中的数据,然后解析逗号。
模式是

\"body\"\s*:\s*\"(.+)\",

字符串

  • "...我对构建自己的正则表达式非常缺乏经验..."*

很简单只是看起来很复杂
我推荐阅读 Wikipedia 文章,因为它概述了整个语法。

另外还有几本书;* O'Reilly Media * 和 * Packt Publishing * 都有一些好的。

下面是一个用 Python 编写的例子。
我使用 re.match 函数来利用模式。
str.split 函数生成一个值列表。

string = '"body": "abc, def, ghi",'
value = re.match(r'\"body\"\s*:\s*\"(.+)\",', string)
value = value.group(1)
strings = value.split(', ')


产出

['abc', 'def', 'ghi']

相关问题