正则表达式在 qoutes 中查找一个又一个键的字符串



>输入:

blalasdl8ujd "key":"value", blblabla asdw "alo":"ebobo",blabla"www":"zzzz">

blalasdl8ujd key[any_chars_here]"value", blabla asdw "alo":"ebobo", bla"www":"zzzz">

我渴望提取value只有key并且知道value"覆盖

在正则表达式之后key.*"(.*?)"返回最后一个用 " ("zzzz") 覆盖的匹配项。 我需要先修复它才能返回。

https://regex101.com/r/CDfhBT/1

代码

在此处查看正在使用的正则表达式

"key"s*:s*"([^"]*)"

为了匹配转义双引号的可能性,您可以使用以下正则表达式:

在此处查看正在使用的正则表达式

"key"s*:s*"((?:(?<!\)\(?:\{2})*"|[^"])*)"

此方法确保双引号字符前面奇数个反斜杠"使得"\"\\"等有效,但\"\\"\\\"无效(这将只输出一个反斜杠字符,因此双引号字符前面"偶数个反斜杠只会导致字符串终止)。

匹配两个字符串

如果您也希望匹配第二个字符串,则可以使用以下正则表达式之一:

bkeyb(?:"s*:s*|.*?)"([^"]*)"
bkeyb(?:"s*:s*|.*?)"((?:(?<!\)\(?:\{2})*"|[^"])*)"

用法

在此处查看正在使用的代码

import re
s = 'blahblah "key":"value","TargetCRS": "Target","TargetCRScode": "vertical Code","zzz": "aaaa" sadzxc "sss"'
r = re.compile(r'''"key"s*:s*"([^"]*)"''')
match = r.search(s)
if match:
print match.group(1)

结果

输入

blahblah "key":"value","TargetCRS": "Target","TargetCRScode": "vertical Code","zzz": "aaaa" sadzxc "sss"
blalasdl8ujd key [any_chars_here] "value", blabla asdw "alo":"ebobo", bla"www":"zzzz"

输出

字符串 1

  • 匹配:"key":"value"
  • 捕获组 1:value

字符串2(使用"匹配两个字符串"下的方法之一时)

  • 匹配:key [any_chars_here] "value"
  • 捕获组 1:value

解释

  • "key"从字面上匹配这个
  • s*匹配任意数量的空格字符
  • :从字面上匹配冒号字符
  • s*匹配任意数量的空格字符
  • "从字面上匹配双引号字符
  • ([^"]*)将集合中不存在的任何字符(除双引号字符"以外的任何字符)捕获任意次数到捕获组 1 中
  • "从字面上匹配双引号字符

匹配两个字符串

  • b断言位置作为单词边界
  • key从字面上匹配
  • b断言位置作为单词边界
  • (?:"s*:s*|.*?)匹配以下任一项
    • "s*:s*
      • "从字面上匹配
      • s*匹配任意数量的空格字符
      • :从字面上匹配
      • s*匹配任意数量的空格字符
    • .*?匹配任意字符次数,但尽可能少
  • "从字面上匹配
  • ([^"]*)捕获除"到捕获组 1 之外的任意数量的字符
  • "从字面上匹配

您可以在key和值组之间使用非贪婪量词.*?

key.*?"(.*?)"

在这里演示。

更新

您可能想知道为什么它会捕获结肠,:.它捕获了这一点,因为这是引号之间的下一件事。因此,您可以在key周围添加可选引号,如下所示:

("?)key1.*?"(.*?)"

另一个演示在这里。

检查这个:

.*("key":"(w*)")

使用组 2:

https://regex101.com/r/66ikH3/2

可能有一种更pythonic的方法可以做到这一点,但是:

s1 = 'blalasdl8ujd "key":"value", blblabla asdw "alo":"ebobo",blabla"www":"zzzz"'
s2 = 'blalasdl8ujd key [any_chars_here] "value", blabla asdw "alo":"ebobo", bla"www":"zzzz"'

def getValue(string, keyName = 'key'):
"""Find next quoted value after a key that may or may not be quoted"""
startKey = string.find(keyName) 
# if key is quoted, adjust value search range to exclude its closing quote
endKey = string.find('"',startKey) if string[startKey-1]=='"' else startKey + len(keyName) 
startValue = string.find('"',endKey+1)+1
return string[startValue:string.find('"',startValue+1)]
getValue(s1) #'value'
getValue(s2) #'value'

我受到这个答案的优雅的启发,但处理引用和未引用的案例使它不仅仅是 1 行。

您可以使用

如下理解:
next(y[1][1:-1] for y in [[l for l in x.split(':')] 
for  x in s2.split(',')] if 'key' in y[0]) # returns 'value' w/o quotes

但这不会处理s2的情况。

最新更新