python-re: Как мне сопоставить альфа-символ - PullRequest
29 голосов
/ 11 января 2010

Как мне сопоставить альфа-символ с регулярным выражением. Я хочу, чтобы персонаж был в \w, но не в \d. Я хочу, чтобы он был совместим с Unicode, поэтому я не могу использовать [a-zA-Z].

Ответы [ 3 ]

48 голосов
/ 11 января 2010

Ваши первые два предложения противоречат друг другу. «в \w, но не в \d» включает подчеркивание. Я предполагаю из вашего третьего предложения, что вы не хотите подчеркнуть.

Использование диаграммы Венна на обороте конверта помогает. Давайте посмотрим на то, что мы не хотим:

(1) символов, которые не совпадают с \w (т.е. не нужно ничего, кроме букв, цифр или подчеркивания) => \W
(2) цифры => \d
(3) подчеркивание => _

Так что нам не нужно ничего в классе персонажей [\W\d_] и, следовательно, мы хотим что-то в классе персонажей [^\W\d_]

Вот простой пример (Python 2.6).

>>> import re
>>> rx = re.compile("[^\W\d_]+", re.UNICODE)
>>> rx.findall(u"abc_def,k9")
[u'abc', u'def', u'k']

Дальнейшие исследования показывают несколько изюминок этого подхода:

>>> import unicodedata as ucd
>>> allsorts =u"\u0473\u0660\u06c9\u24e8\u4e0a\u3020\u3021"
>>> for x in allsorts:
...     print repr(x), ucd.category(x), ucd.name(x)
...
u'\u0473' Ll CYRILLIC SMALL LETTER FITA
u'\u0660' Nd ARABIC-INDIC DIGIT ZERO
u'\u06c9' Lo ARABIC LETTER KIRGHIZ YU
u'\u24e8' So CIRCLED LATIN SMALL LETTER Y
u'\u4e0a' Lo CJK UNIFIED IDEOGRAPH-4E0A
u'\u3020' So POSTAL MARK FACE
u'\u3021' Nl HANGZHOU NUMERAL ONE
>>> rx.findall(allsorts)
[u'\u0473', u'\u06c9', u'\u4e0a', u'\u3021']

U + 3021 (HANGZHOU NUMERAL ONE) обрабатывается как числовой (следовательно, он соответствует \ w), но кажется, что Python интерпретирует «цифра» как «десятичная цифра» (категория Nd), поэтому он не соответствует \ d

U + 2438 (ЗАПИСЬ МАЛЕНЬКОГО ЛАТИНСКОГО Y) не соответствует \ w

Все иероглифы CJK классифицируются как "буквы" и, таким образом, соответствуют \ w

Независимо от того, является ли какой-либо из вышеперечисленных пунктов проблемой, или нет, такой подход является лучшим, что вы получите из модуля re, выпущенного в настоящее время. Синтаксис типа \ p {letter} находится в будущем.

2 голосов
/ 11 января 2010

А как же:

\p{L}

Вы можете использовать этот документ в качестве ссылки: Регулярные выражения Unicode

РЕДАКТИРОВАТЬ: Кажется Python не обрабатывает выражения Unicode . Взгляните на эту ссылку: Обработка ударных символов с регулярными выражениями Python - [A-Z] просто недостаточно хорош (больше не активен, ссылка на интернет-архив)

Другие ссылки:


Для потомков вот примеры в блоге:

import re
string = 'riché'
print string
riché

richre = re.compile('([A-z]+)')
match = richre.match(string)
print match.groups()
('rich',)

richre = re.compile('(\w+)',re.LOCALE)
match = richre.match(string)
print match.groups()
('rich',)

richre = re.compile('([é\w]+)')
match = richre.match(string)
print match.groups()
('rich\xe9',)

richre = re.compile('([\xe9\w]+)')
match = richre.match(string)
print match.groups()
('rich\xe9',)

richre = re.compile('([\xe9-\xf8\w]+)')
match = richre.match(string)
print match.groups()
('rich\xe9',)

string = 'richéñ'
match = richre.match(string)
print match.groups()
('rich\xe9\xf1',)

richre = re.compile('([\u00E9-\u00F8\w]+)')
print match.groups()
('rich\xe9\xf1',)

matched = match.group(1)
print matched
richéñ
0 голосов
/ 03 марта 2016

Вы можете использовать одно из следующих выражений для соответствия одной букве:

(?![\d_])\w

или

\w(?<![\d_])

Здесь я соответствую \w, но убедитесь, что [\d_] не соответствует до / после этого.

Из документов:

(?!...)
Matches if ... doesn’t match next. This is a negative lookahead assertion. For example, Isaac (?!Asimov) will match 'Isaac ' only if it’s not followed by 'Asimov'.

(?<!...)
Matches if the current position in the string is not preceded by a match for .... This is called a negative lookbehind assertion. Similar to positive lookbehind assertions, the contained pattern must only match strings of some fixed length and shouldn’t contain group references. Patterns which start with negative lookbehind assertions may match at the beginning of the string being searched.
...