Python Юникод строка - позиция - PullRequest
0 голосов
/ 03 мая 2020

Я застрял с получением позиции внутри строки. Я читаю содержимое файла

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

- == EDIT == - Теперь я могу лучше показать, в чем проблема:

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"}]}}"

, я всегда получаю «неправильный» результат :( Поэтому чтение файла - это моя проблема, потому что впоследствии строки не совпадают - даже длина отличается!

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Если эта строка представляет ✅ Offizielle Kanäle ?? ?? ??, как предполагает ответ @ scribe, то я думаю, что вы столкнетесь с проблемой, упомянутой здесь: Преобразование в эмодзи

Поэтому я предлагаю заменить

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:] должен получить то, что вы просили.

0 голосов
/ 03 мая 2020

Если ваш файл 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...