Соответствует юникоду в регулярных выражениях - PullRequest
4 голосов
/ 26 октября 2008

Я сопоставляю идентификаторы, но теперь у меня проблема: мои идентификаторы могут содержать символы Юникода. Поэтому старого способа сделать что-то недостаточно:

t_IDENTIFIER = r"[A-Za-z](\\.|[A-Za-z_0-9])*"

В синтаксическом анализаторе моего языка разметки я сопоставляю символы юникода, разрешая всем символам, кроме тех, которые я явно использую, потому что мой язык разметки содержит только два или три символа, которые мне нужно экранировать.

Как мне сопоставить все символы Юникода с регулярными выражениями Python и ply? И это вообще хорошая идея?

Я бы хотел, чтобы люди использовали идентификаторы, такие как Ω »« ° foo² väli π, в качестве идентификаторов (имена переменных и тому подобное) в своих программах. Черт! Я хочу, чтобы люди могли писать программы на своем родном языке, если это практично! В любом случае, в настоящее время юникод поддерживается в самых разных местах, и он должен распространяться.

Редактировать: Классы символов POSIX, похоже, не распознаются регулярными выражениями Python.

>>> import re
>>> item = re.compile(r'[[:word:]]')
>>> print item.match('e')
None

Редактировать: Чтобы лучше объяснить, что мне нужно. Мне нужно регулярное выражение, которое соответствует всем печатным символам Юникода, но не символам ASCII.

Редактировать: r "\ w" делает немного то, что я хочу, но оно не соответствует «», и мне также нужно регулярное выражение, которое не соответствует числам.

Ответы [ 5 ]

5 голосов
/ 27 октября 2008

модуль re поддерживает синтаксис \ w, который:

Если установлен UNICODE, это будет соответствовать символы [0-9_] плюс все, что есть классифицируется как буквенно-цифровой в База данных свойств символов Юникода.

поэтому в следующих примерах показано, как сопоставлять идентификаторы Unicode:

>>> import re
>>> m = re.compile('(?u)[^\W0-9]\w*')
>>> m.match('a')
<_sre.SRE_Match object at 0xb7d75410>
>>> m.match('9')
>>> m.match('ab')
<_sre.SRE_Match object at 0xb7c258e0>
>>> m.match('a9')
<_sre.SRE_Match object at 0xb7d75410>
>>> m.match('unicöde')
<_sre.SRE_Match object at 0xb7c258e0>
>>> m.match('ödipus')
<_sre.SRE_Match object at 0xb7d75410>

Таким образом, вы ищете выражение: (? U) [^ \ W0-9] \ w *

3 голосов
/ 14 декабря 2011

Вам необходимо передать reflags параметра передачи в lex.lex:

lex.lex(reflags=re.UNICODE)
1 голос
/ 26 октября 2008

Проверьте ответы на этот вопрос

Удаление непечатных символов из строки в Python

вам просто нужно использовать другие категории символов Юникода вместо

1 голос
/ 26 октября 2008

Решил с помощью Винко.

Я понял, что получить диапазон Юникода просто глупо. Поэтому я сделаю это:

symbols = re.escape(''.join([chr(i) for i in xrange(33, 127) if not chr(i).isalnum()]))
symnums = re.escape(''.join([chr(i) for i in xrange(33, 127) if not chr(i).isalnum()]))

t_IDENTIFIER = "[^%s](\\.|[^%s])*" % (symnums, symbols)

Я не знаю о классах символов Unicode. Если этот юникодный материал начинает становиться слишком сложным, я могу просто поставить оригинальный на место. Поддержка UTF-8 по-прежнему обеспечивает поддержку на токенах STRING, что более важно.

Редактировать: С другой стороны, я начинаю понимать, почему в языках программирования не так много поддержки юникода. Это уродливый взлом, а не удовлетворительное решение.

0 голосов
/ 26 октября 2008

Возможно Классы символов POSIX подходят вам?

...