python-re: как сопоставить Альфа-символ

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

3 ответов


ваши первые два предложения противоречат друг другу. - in \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

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


о:

\p{L}

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

EDIT: кажется 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éñ

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

(?![\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.