Совпадение с юникодом в регулярных выражениях слоя

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

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

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

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

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

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

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

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

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


person Cheery    schedule 26.10.2008    source источник
comment
Также не похоже, что Python PCRE также понимает классы предикатов: \p{IsAlpha}   -  person Axeman    schedule 27.10.2008


Ответы (5)


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

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

поэтому в следующих примерах показано, как сопоставлять идентификаторы 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*

person Florian Bösch    schedule 26.10.2008
comment
Сейчас. Это удовлетворительное решение! - person Cheery; 27.10.2008
comment
Цитата из документации Python верна, но примеры вводят в заблуждение. Вы можете просто использовать флаг UNICODE с \w вместо излишне длинного выражения: re.match(r'\w+', "ünıcodê", re.UNICODE) - person Walter; 27.10.2008
comment
Вальтер, вы не правильно прочитали вопрос: 1) цель - это идентификатор в языке программирования, который обычно не начинается с 0-9. 2) синтаксический анализатор (ply) занимается синтаксическим анализом, и его нельзя контролировать, как он будет вызывать сопоставление, поэтому требуется (?u). - person Florian Bösch; 27.10.2008
comment
Re: контроль того, как ply вызывает соответствие, см. ответ Станислава ниже - person Paul Du Bois; 20.12.2011

В lex.lex вам нужно передать переадресацию параметров передачи:

lex.lex(reflags=re.UNICODE)
person Stan    schedule 14.12.2011

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

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

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

person Vinko Vrsalovic    schedule 26.10.2008

Решил с помощью Vinko.

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

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)

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

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

person Cheery    schedule 26.10.2008

Вероятно, вам подходят классы символов POSIX?

person Tomalak    schedule 26.10.2008
comment
Их нет в движке регулярных выражений Python. - person Vinko Vrsalovic; 26.10.2008