我想用json文档中的双撇号替换嵌套的双引号。
我尝试了以下代码,但是我的正则表达式模式未选择需要更改的正确组。
# fixing double quote
try:
result = re.search('claimReviewed": "(.*)",',page,re.UNICODE | re.IGNORECASE)
if result is not None:
double_quoted = result.group(1)
print(double_quoted)
double_quoted_fixed = double_quoted.replace('"', '\'\'')
page = page.replace(double_quoted, double_quoted_fixed)
except AttributeError as e:
print(e)
return page
我的测试字符串是:
"sameAs": "https://www.facebook.com/sonnoktasayfasi/photos/a.673944945978789/2319632444743356/?type=3&theater"
},
"datePublished": "02/05/2019"
},
"claimReviewed": "İDDİA: Diyanet İşleri Başkanlığı ''Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin" şeklinde bir açıklama yaptı. "
我的代码段返回以下内容,仅更改为第一双引号:
"sameAs": "https://www.facebook.com/sonnoktasayfasi/photos/a.673944945978789/2319632444743356/?type=3&theater"
},
"datePublished": "02/05/2019"
},
"claimReviewed": "İDDİA: Diyanet İşleri Başkanlığı ''Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin" şeklinde bir açıklama yaptı. "
,所需的行为是: 第一个正则表达式模式应分组
İDDİA: Diyanet İşleri Başkanlığı "Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin" şeklinde bir açıklama yaptı.
,然后将其替换为双撇号,所需的输出应如下:
"claimReviewed": "İDDİA: Diyanet İşleri Başkanlığı ''Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin'' şeklinde bir açıklama yaptı. ",
答案 0 :(得分:3)
您输入的数据是HTML和嵌入式JSON,而JSON则被破坏了。
我将尽可能使用解析器来解决这个问题。对于HTML,我们可以使用lxml
,使用XPath可以轻松获取有趣元素(<script type="application/ld+json">
)的文本内容。
有了元素文本后,可以使用json.loads()
。此方法适用于示例页面上的第一个此类元素,但不适用于第二个元素,出现"Expecting ',' delimiter"
错误。
有问题的部分是:
"claimReviewed": "İDDİA: Diyanet İşleri Başkanlığı "Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin" şeklinde bir açıklama yaptı.
",
正确的是:
"claimReviewed": "İDDİA: Diyanet İşleri Başkanlığı \"Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin\" şeklinde bir açıklama yaptı.\n\n ",
所以有两件事要解决:
\n
之后,JSON应该进行解析。
我们可以使用JSON解析器中的异常信息在JSON中进行适当的修复,反复尝试对其进行解析,直到解析成功或遇到某种尚不知道如何解决的错误为止。 / p>
# json_utils.py
import json
class JsonRepairError(Exception):
def __init__(self, e, text):
message = "Don't know how to fix '%s', position %s (-->%s<--)" % (e.msg, e.pos, text[e.pos-5:e.pos+5])
super().__init__(message)
self.text = text
def json_repair(text):
while True:
try:
return json.loads(text)
except json.decoder.JSONDecodeError as e:
if e.msg == "Expecting ',' delimiter":
if text[e.pos-1] == '"':
text = text[:e.pos-1] + '\\' + text[e.pos-1:]
continue
elif text[e.pos-2] == '"':
text = text[:e.pos-2] + '\\' + text[e.pos-2:]
continue
elif e.msg == "Invalid control character at":
if text[e.pos] == '\n':
text = text[:e.pos] + '\\n' + text[e.pos+1:]
continue
raise JsonRepairError(e, text) from None
我们可以这样使用:
import requests
from html import unescape
from lxml import html
from json_utils import json_repair
response = requests.get("https://gist.githubusercontent.com/isspek/6b687e69bbfbb1f5519de5c13e92e4da/raw")
tree = html.fromstring(response.content)
elem = tree.findall('.//script[@type="application/ld+json"]')[-1]
text = unescape(elem.text) # this gets rid of the stray in the data
data = json_repair(text)
print(data["claimReviewed"])
这将打印正确的输出:
İDDİA: Diyanet İşleri Başkanlığı "Çocuklara Zekâ Geliştirici Oyuncaklar Vermeyin"
şeklinde bir açıklama yaptı.
优点是可以轻松地将这种方法适应以前未处理的任何类型的错误-只需添加几对if
/ elif
检查并进行适当的修复即可。使用正则表达式很难做到这一点。它对HTML格式的更改也更具弹性,并且总体上更易于维护。
答案 1 :(得分:1)
您可以使用以下正则表达式:
(:\s+")(.*(?:\n(?!\s*"[^"\n:]+":).*)*)
请参见regex demo
详细信息
(:\s+")
-第1组::
,1个以上的空格,"
(.*(?:\n(?!\s*"[^"\n:]+":).*)*)
-第2组:
.*
-除换行符以外的任意0+个字符,并且尽可能多(?:\n(?!\s*"[^"\n:]+":).*)*
-重复0次或更多次
\n(?!\s*"[^"\n:]+":)
-换行符,其后不跟0+空格,"
,除换行符之外的1+个字符,"
和:
,然后是{{1} }子字符串":
-除换行符以外的任意0+个字符,并且尽可能多请参见Python demo:
.*