Мы создаем программу на Python 3, которая вызывает программу на Java. Java-программа (сторонняя программа, которую мы не можем изменить) используется для токенизации строк (поиска слов) и предоставления других аннотаций. Эти аннотации представлены в виде смещения символов.
Например, мы можем предоставить программе строковые данные, такие как "lovely weather today"
. Это обеспечивает что-то вроде следующего вывода:
0,6
7,14
15,20
Где 0,6
- это смещения, соответствующие слову "lovely", 7,14
- это смещения, соответствующие слову "weather", и 15,20
- это смещения, соответствующие слову "today" в исходной строке. Мы читаем эти смещения в Python, чтобы извлечь текст в этих точках и выполнить дальнейшую обработку.
Все хорошо, пока персонажи находятся в базовой многоязычной плоскости ( BMP ). Однако, если это не так, смещения, сообщаемые этой Java-программой, обнаруживают все ошибки на стороне Python.
Например, учитывая строку "I feel ? today"
, программа на Java выведет:
0,1
2,6
7,9
10,15
На стороне Python они переводятся как:
0,1 "I"
2,6 "feel"
7,9 "? "
10,15 "oday"
Где последний индекс технически недействителен. Java видит «?» как длину 2, что приводит к тому, что все аннотации после этой точки отключаются на единицу с точки зрения программы Python.
Предположительно, это происходит потому, что Java кодирует строки внутренним образом UTF-16esqe, а все строковые операции действуют на эти кодовые единицы UTF-16esque . С другой стороны, строки Python работают с реальными символами Юникода (кодовые точки). Поэтому, когда символ появляется вне BMP, Java-программа видит его как длину 2, тогда как Python видит его как длину 1.
Итак, теперь возникает вопрос: как лучше всего «исправить» эти смещения до того, как Python их использует, чтобы подстроки аннотации соответствовали тому, что Java-программа намеревалась вывести?