アルファベット文字を正規表現と一致させるにはどうすればよいですか。\w
に入っているが入っていないキャラクターが欲しい\d
。Unicode 互換にしたいので、使用できません[a-zA-Z]
。
3 に答える
最初の 2 つの文は互いに矛盾しています。"in \w
but is not in \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 (CIRCLED LATIN SMALL LETTER Y) は一致しません \w
すべての CJK 表意文字は「文字」として分類されるため、\w に一致します。
上記の 3 つのポイントのいずれかが懸念されるかどうかに関係なく、そのアプローチは、現在リリースされている re モジュールから得られる最善の方法です。\p{letter} のような構文は将来のものです。
どうですか:
\p{L}
このドキュメントを参照として使用できます: Unicode 正規表現
編集: 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éñ
次の式のいずれかを使用して、1 つの文字に一致させることができます。
(?![\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.