【问题标题】:Python unicode string - positionPython unicode 字符串 - 位置
【发布时间】:2020-05-03 07:56:15
【问题描述】:

我坚持在字符串中获取位置。 我读了一个文件的内容

with io.open(testfile, 'r', encoding='utf-8') as f

\u2705 Offizielle Kan\u00e4le \ud83c\udde9\ud83c\uddea  \ud83c\udde6\ud83c\uddf9 \ud83c\udde8\ud83c\udded\n@GET_THIS_STING

我该怎么办 - “\u2705” 算作 1 个字母? 那么位置 36 将是 @GET_THIS_STING 的开始

--== 编辑 ==-- 我现在可以更好地说明问题所在:

import json
from io import open

line = '{"message":{"message_id":3052,"text":"\u2705 Offizielle Kan\u00e4le \ud83c\udde9\ud83c\uddea  \ud83c\udde6\ud83c\uddf9 \ud83c\udde8\ud83c\udded\\n@GET_THIS_STING\\n123456789","entities":[{"offset":36,"length":26,"type":"mention"}]}}'
myjson = json.loads(line)
text = myjson.get("message", {}).get("text", None)
print(str(text).encode('utf-8', 'replace').decode())
print("string length: " + str(len(text)))
print(text[36:36+15])

print("-------------")

with open("/home/pi/telegram/phpLogs/test.txt", 'r', encoding='utf-8', errors="surrogateescape") as f:
    for line in f:
        myjson = json.loads(line)

        text = myjson.get("message", {}).get("text", None)
        print(text)
        print("string length: " + str(len(text)))
        print(text[36:36+15])

结果:

✅ Offizielle Kanäle ????  ???? ????
@GET_THIS_STING
123456789
string length: 61
@GET_THIS_STING
-------------
✅ Offizielle Kanäle ????????  ???????? ????????
@GET_THIS_STING123456789
string length: 54
HIS_STING123456

因此,当我将代码 (UTF-8) 中的字符串作为变量 (String) 时,一切正常。 但是当我创建一个包含内容的文件并阅读它时

"{"message":{"message_id":3052,"text":"\u2705 Offizielle Kan\u00e4le \ud83c\udde9\ud83c\uddea  \ud83c\udde6\ud83c\uddf9 \ud83c\udde8\ud83c\udded\\n@GET_THIS_STING\\n123456789","entities":[{"offset":36,"length":26,"type":"mention"}]}}"

我总是收到“错误”的结果 :( 所以读取文件是我的问题,因为之后的字符串不一样——甚至长度都不一样!

【问题讨论】:

  • 哪个 Python 版本?
  • python 版本 3.6 在带有 Raspbian 的树莓上 是的 - 该文件包含带有 \u 的字符串

标签: python unicode encoding position substring


【解决方案1】:

如果这个字符串代表✅ Offizielle Kanäle ?? ?? ??,正如@scribe 的回答所建议的那样,那么我认为你遇到了这里提到的问题:Converting to Emoji

因此我建议更换

with io.open(testfile, 'r', encoding='utf-8') as f:
    text = f.read() # you didn't show it but probably that's what you have done

with open(testfile, 'r', encoding='ascii') as f:
    text = json.load(f)

或者,如果文件是“JSON 行”而不是单个 JSON:

with open(testfile, 'r', encoding='ascii') as f:
    for line in f:
        text = json.loads(line)

然后text 将是一个正确的Unicode 字符串,所以text[36:] 应该会得到你想要的。

【讨论】:

  • 非常接近我需要的解决方案 - 现在似乎不计算 \n 了。但这也应该计算在内 - 在我的示例中,我将使用您的代码“GET_THIS_STING”,而没有由于换行符而丢失的“@”。这个问题改变的结果越多 \n 我有。对于每个 \n,结果都会减少它的数量
  • edit: emojies 似乎有问题——总之我的结果丢失了 6 个字母——所以它变成了 6——“IS_STING”——\n 不是问题,它似乎被计算在内-- 所以这 3 个标志不算正确
  • 这似乎是代理字符的问题:stackoverflow.com/questions/38147259/… 所以尝试添加:text = text.encode('utf-16', 'surrogatepass').decode('utf-16')
  • 我得到了 myjson = myjson.encode('utf-16', 'surrogatepass').decode('utf-16') --- AttributeError: 'dict' object has no attribute 'encode '
  • \ud83c\udde9\ud83c\uddea 应计为 4,但由于 Flag 被解释为“DE”而计为 2
【解决方案2】:

如果您的文件 text.txt 确实包含,

\u2705 Offizielle Kan\u00e4le \ud83c\udde9\ud83c\uddea  \ud83c\udde6\ud83c\uddf9 \ud83c\udde8\ud83c\udded\n@GET_THIS_STING

试试:

with open('text.txt', 'r', encoding='utf-8') as f:
    str = f.read()
    normal_str = ''
    i, n = 0, 0
    while i < len(str):
        if str[i: i + 2] == '\\u':
            i += 6
            normal_str += 'x'
        elif str[i: i + 2] == '\\n':
            i += 2
            normal_str += 'x'
        else:
            normal_str += str[i]
            i += 1
        n += 1
    print(normal_str)
    print(normal_str[36:36 + 15])

而且,这个输出:

x Offizielle Kanxle xxxx  xxxx xxxxx@GET_THIS_STING

@GET_THIS_STING

使用看起来像这样的文件text.txt

✅ Offizielle Kanäle ??  ?? ??
@GET_THIS_STING

我们可以,

with open('text.txt', 'r', encoding='utf-8') as f:
    str = f.read()
    index = str.find('@')
    print('char @ is at index: {}'.format(index))
    print(str[index:])

它输出,

char @ is at index: 30
@GET_THIS_STING

【讨论】:

  • 问题是,我无法搜索职位 - 我有职位 - 所以我必须使用 mystring[36:36+15] 该字符串是我从 Telegram API 存储的结果- 你有一个带有“偏移”、“长度”的实体列表,可以知道文本中的位置
  • 如果有字符串为什么不能搜索?您正在阅读的文件的具体内容是什么?
  • 我在主帖 1:1 中添加了一个示例。我的问题仍然是,从文件中读取字符串时,我得到的结果与直接将代码中的字符串作为变量处理不同。所以很确定是编码问题。
  • 您的帖子不太容易阅读。如果您需要帮助,请获取示例字符串并手动对其执行功能并显示所需的输出。如果我了解您的问题,那么我的答案的最后更新应该可以解决。只要您不需要未正确编码的数据,您的字符串的编码方式就无关紧要。即使错误,您也希望编码保持一致,以便过滤掉您真正关心的数据。
猜你喜欢
  • 2017-11-19
  • 2011-11-12
  • 2023-03-30
  • 2021-11-03
  • 1970-01-01
  • 2011-11-07
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多