【问题标题】:Capture strings inside escaped quotes在转义引号内捕获字符串
【发布时间】:2020-02-20 00:53:38
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: python regex presto


    【解决方案1】:

    这样的事情怎么样:

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

    Demo.

    或确保\\ 仅成对匹配:

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

    Demo.

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


    更新:

    您的新测试字符串仍将与上述模式匹配。如果您愿意,可以将Bank:.* 替换为Bank:[ ]Demo1 - Demo2.

    解释:(改变你的模式)

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

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

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

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

    【讨论】:

    • 我已将测试字符串更新为更精确...我只需要查找“银行”字样,然后在花背中查找 ID 和名称(带或不带转义字符)跨度>
    • @user330612 您更新的测试字符串使上述模式的一部分变得不必要,但它仍然可以工作。是否需要支持原始测试字符串?
    • 我不需要支持原始测试字符串..抱歉造成混淆。如果正则表达式可以更清晰地匹配新的测试字符串,那就太好了。谢谢您的帮助。还可以对正则表达式的作用进行一些解释
    • @user330612 再想一想,我仍然会使用相同的模式(不需要去掉[^{"] 部分。如果你愿意,你可以用Bank[ ] 替换Bank:.*。我不过会添加解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    相关资源
    最近更新 更多