Я попробовал несколько сопоставлений регулярных выражений Python с Unicode и обнаружил, что они не работают так, как я ожидал, ни в re, ни в регулярных выражениях. Например, r"\w" не соответствует строкам, содержащим "x", если они есть. определенные символы, предшествующие «x» в сопоставляемой строке.
Персонажи, которые кажутся доставляющими неприятности:
Неназначенные символы, предшествующие личному использованию (U+D7FC...U+DFFF)
Символы частного использования (U+E000...)
Но некоторые неназначенные символы работают нормально (U+0378). И по крайней мере некоторые символы над областью «Частное использование» работают нормально (U+F900).
Я пробовал искать SO, в Интернете, а также в документах re и regex. (например, https://docs.python.org/3.11/library/re.html#module-re и https://pypi.org/project/regex/), но не удалось найти подходящие информация.
Это известное/ожидаемое поведение? Сначала я подумал, может быть, не Unicode символы просто делают совпадение недействительным, и кто-то решил, что Private использование такое же, как и неназначенное; но:
U+378 не назначен и работает нормально.
Личное использование, конечно, не должно иметь такого поведения, даже если оно было неназначенным.
Все работает, когда совпадение удовлетворено до того, как оно увидит шаткого персонажа.
import sys
import re
import unicodedata
import regex
def test(theLib):
print("\nWith %s:" % (theLib.__name__))
print("x: ", theLib.match(r"\w", "x"))
print("0378: ", theLib.match(r"\w", "x \u0378")) # Unassigned
print("E010: ", theLib.match(r"\w", "\uE010")) # Private use char
print("x E010: ", theLib.match(r"\w", "x \uE010"))
print("E010 x: ", theLib.match(r"\w", "\uE010 x"))
print("D7FB x: ", theLib.match(r"\w", "\uD7FB x")) # HANGUL JONGSEONG PHIEUPH-THIEUTH
print("D7FC x: ", theLib.match(r"\w", "\uD7FC x")) # Unassigned
print("D800 x: ", theLib.match(r"\w", "\uD800 x"))
print("F900 x: ", theLib.match(r"\w", "\uF900 x"))
print(sys.version)
test(re)
test(regex)
производит:
3.11.9 (main, Apr 2 2024, 08:25:04) [Clang 15.0.0 (clang-1500.3.9.4)]
With re:
x: <re.Match object; span=(0, 1), match='x'>
0378: <re.Match object; span=(0, 1), match='x'>
E010: None
x E010: <re.Match object; span=(0, 1), match='x'>
E010 x: None
D7FB x: <re.Match object; span=(0, 1), match='ퟻ'>
D7FC x: None
D800 x: None
F900 x: <re.Match object; span=(0, 1), match='豈'>
With regex:
x: <regex.Match object; span=(0, 1), match='x'>
0378: <regex.Match object; span=(0, 1), match='x'>
E010: None
x E010: <regex.Match object; span=(0, 1), match='x'>
E010 x: None
D7FB x: <regex.Match object; span=(0, 1), match='ퟻ'>
D7FC x: None
D800 x: None
F900 x: <regex.Match object; span=(0, 1), match='豈'>
🤔 А знаете ли вы, что...
С Python можно создавать кросс-платформенные приложения для Windows, macOS и Linux.
Например, r"\w" не соответствует строкам, содержащим "x", если в сопоставляемой строке есть определенные символы, предшествующие "x".
Конечно, он не соответствует «x», если перед ним стоят другие символы. Тогда строка не начинается с «x». А re.match
— для сопоставления с самого начала. Итак, на самом деле вы проверяете, соответствует ли \w
этим определенным символам.