在Python(3.5.0)中,我想打印一个字符串containsig unicode符号(更准确地说,是以JSON格式从维基词典中检索到的IPA符号)到屏幕或文件,例如
print("\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n")
正确打印
ˈwɔːtəˌmɛlən
- 但是,每当我在变量中使用字符串时,例如
ipa = '\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n'
print(ipa)
它只是打印出字符串,即
\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n
没有多大帮助。
我已经尝试了几种方法来避免这种情况(例如通过deocde
/ encode
),但非此方法有帮助。
我无法使用
u'\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n'
要么因为我已经将字符串检索为变量(作为正则表达式匹配的结果),并且在我的代码中没有任何点输入实际的文字。
在转换JSON结果时,我可能犯了一个错误;到现在为止,我已经使用str(f.read())
将字节流转换为字符串,通过正则表达式提取IPA部分(并在双反斜杠上完成替换)并将其存储在字符串变量中。
编辑:
这是我到目前为止的代码:
def getIPAen(word):
url = "https://en.wiktionary.org/w/api.php?action=query&titles=" + word + "&prop=revisions&rvprop=content&format=json"
jsoncont = str((urllib.request.urlopen(url)).read())
jsonmatch = re.search("\{IPA\|/(.*?)/\|", jsoncont).group(1)
#print("jsomatch: " + jsonmatch)
ipa = jsonmatch.replace("\\\\", "\\")
#print("ipa: " + ipa)
print(ipa)
使用json.loads
进行修改后:
def getIPAen(word):
url = "https://en.wiktionary.org/w/api.php?action=query&titles=" + word + "&prop=revisions&rvprop=content&format=json"
jsoncont = str((urllib.request.urlopen(url)).read())
jsonmatch = re.search("\{IPA\|/(.*?)/\|", jsoncont).group(1)
#print("jsonmatch: " + jsonmatch)
jsonstr = "\"" + jsonmatch + "\""
#print("jsonstr: " + jsonstr)
jsonloads = json.loads(jsonstr)
#print("jsonloads: " + jsonloads)
print(jsonloads)
对于这两个版本,使用
进行调用时getIPAen("watermelon")
我得到的是:
\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n
有没有办法让字符串打印/写入已解码,即使作为变量传递?
答案 0 :(得分:5)
你没有这个价值:
ipa = '\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n'
因为 值打印得很好:
>>> ipa = '\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n'
>>> print(ipa)
ˈwɔːtəˌmɛlən
您至少拥有文字\
和u
字符:
ipa = '\\u02c8w\\u0254\\u02d0t\\u0259\\u02ccm\\u025bl\\u0259n'
这些\\
序列各自一个反斜杠,但已转义。由于这是JSON,字符串可能也被双引号括起来:
ipa = '"\\u02c8w\\u0254\\u02d0t\\u0259\\u02ccm\\u025bl\\u0259n"'
因为该字符串具有文字反斜杠,这正是正在打印的内容:
>>> ipa = '"\\u02c8w\\u0254\\u02d0t\\u0259\\u02ccm\\u025bl\\u0259n"'
>>> print(ipa)
"\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n"
>>> ipa[1]
'\\'
>>> print(ipa[1])
\
>>> ipa[2]
'u'
注意值 echoed 如何显示可以复制并粘贴回Python的字符串文字,因此\
字符会再次转义。
该值是有效的JSON,也使用\uhhhh
转义序列。将其解码为JSON:
import json
print(json.loads(ipa))
现在你有一个合适的Python值:
>>> import json
>>> json.loads(ipa)
'ˈwɔːtəˌmɛlən'
>>> print(json.loads(ipa))
ˈwɔːtəˌmɛlən
请注意,在Python 3中,即使repl()
为您创建文字,也会直接打印所有代码点。 json.loads()
结果直接显示值中的所有文本,即使大多数是非ASCII。
此值不包含文字反斜杠或u
字符:
>>> result = json.loads(ipa)
>>> result[0]
'ˈ'
>>> result[1]
'w'
作为旁注,在调试此类问题时,您确实希望使用repr()
和ascii()
函数,以便获得可以正确重现字符串值的表示:
>>> print(repr(ipa))
'"\\u02c8w\\u0254\\u02d0t\\u0259\\u02ccm\\u025bl\\u0259n"'
>>> print(ascii(ipa))
'"\\u02c8w\\u0254\\u02d0t\\u0259\\u02ccm\\u025bl\\u0259n"'
>>> print(repr(result))
'ˈwɔːtəˌmɛlən'
>>> print(ascii(result))
'\u02c8w\u0254\u02d0t\u0259\u02ccm\u025bl\u0259n'
请注意,对于具有超出Latin-1范围的实际Unicode代码点的字符串,只有ascii()
会生成实际的\uhhhh
转义序列。 (对于repl()
输出,如果终端或控制台无法处理特定字符,Python仍可以回退到\uhhhh
转义。
至于您的更新,只需将整个响应解析为JSON,然后从中加载正确的数据。您的代码会将bytes
响应正文转换为repr()
(str()
字节调用不解码数据;而是双倍逃脱这种方式)。将网络中的字节解码为UTF-8,然后将该数据提供给json.loads()
:
import json
import re
import urllib.request
from urllib.parse import quote_plus
baseurl = "https://en.wiktionary.org/w/api.php?action=query&titles={}&prop=revisions&rvprop=content&format=json"
def getIPAen(word):
url = baseurl.format(quote_plus(word))
jsondata = urllib.request.urlopen(url).read().decode('utf8')
data = json.loads(jsondata)
for page in data['query']['pages'].values():
for revision in page['revisions']:
if 'IPA' in revision['*']:
ipa = re.search(r"{IPA\|/(.*?)/\|", revision['*']).group(1)
print(ipa)
请注意,我还要确保引用 word
值到URL查询字符串中。
上面列出了它找到的任何IPA:
>>> getIPAen('watermelon')
ˈwɔːtəˌmɛlən
>>> getIPAen('chocolate')
ˈtʃɒk(ə)lɪt