web-dev-qa-db-ja.com

python-re:アルファベット文字を一致させる方法

アルファ文字を正規表現と一致させるにはどうすればよいですか。 \wにはあるが\dにはない文字が必要です。ユニコード互換にしたいので、[a-zA-Z]を使用できません。

30
basaundi

最初の2つの文は互いに矛盾しています。 「\w内にあるが\d内にない」には、アンダースコアが含まれます。 3番目の文から、アンダースコアは不要だと思います。

封筒の裏側にベン図を使用すると役立ちます。私たちが望まないものを見てみましょう:

(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は、「数字」を「10進数」(カテゴリNd)を意味すると解釈するため、そうではありません。\dに一致しない

U + 2438(円形の小文字小文字Y)が\ wと一致しません

すべてのCJK表意文字は「文字」として分類されるため、\ wに一致します

上記の3つのポイントのいずれかが問題であるかどうかにかかわらず、そのアプローチは、現在リリースされているreモジュールから抜け出すのに最適です。\p {letter}のような構文は将来的に使用されます。

49
John Machin

何について:

\p{L}

このドキュメントを参照として使用できます: nicode正規表現

編集:PythonはUnicode式を処理しません 。このリンクを確認してください: アクセント付き文字をPython正規表現-[AZ]で処理するだけでは十分ではありません (アクティブではなくなり、インターネットアーカイブにリンクしています) )

別の参照:


後世のために、ここにブログの例があります:

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éñ
2
Rubens Farias

次の式のいずれかを使用して、単一の文字を照合できます。

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