首页 > 解决方案 > 在转义引号内捕获字符串

问题描述

我有 3 个这种格式的字符串

Bank: {"955974044748481":["BANK_A"]}
{"reason": "Bank: {"455049295219902":["BANK_B"]}"}
{"reason": "Bank: {\\"1876212592475597\\":[\\"BANK_C\\"]}"}

我需要在 presto SQL 语句中使用单个正则表达式从这些字符串中提取bank_id和。bank_name

我试过这个正则表达式,但它只捕获前两个而不是最后一个有转义字符的。https://regex101.com/r/ejW68x/1

Bank: {"(.*)":\["(.*)"\]}

捕捉所有 3 种变化的正确方法是什么?

标签: pythonregexpresto

解决方案


像这样的东西怎么样:

Bank:.*{(?:\\\\)?"([^{"]*?)(?:\\\\)?":\[(?:\\\\)?"(.*?)(?:\\\\)?"\]}

演示

或确保\\仅成对匹配:

Bank:.*{((?:\\\\)?)"([^{"]*?)\1":\[((?:\\\\)?)"(.*?)\3"\]}

演示

请注意,在第二种情况下,您的捕获将在组 #2 和 #4 中。


更新:

您的新测试字符串仍将与上述模式匹配。如果你愿意,你可以直接替换Bank:.*演示1 -演示2 。Bank:[ ]

说明:(更改您的模式)

  • 添加(?:\\\\)?了 --> 一个可选的非捕获组来匹配两个反斜杠字符。

  • 将您的第一个捕获组(.*)替换([^{"]*?)为以避免匹配双引号和{字符(这对于您的第一个测试字符串尤其必要)。此外,将它从贪婪转换为懒惰(通过添加?)以避免捕获转义字符(\\)(如果存在)。

  • (.*?)出于同样的原因,也使第二个捕获组变得懒惰。

  • 在第二种模式中,(?:\\\\)?被添加到捕获组中,以便可以使用反向引用(即,\1\3)。这样做的目的是仅在两个双引号字符都被转义(前面带有\\)时才匹配。


推荐阅读