2010-01-10 2 views
25

Wie kann ich ein Alpha-Zeichen mit einem regulären Ausdruck abgleichen? Ich möchte ein Zeichen, das in \w ist, aber nicht in \d ist. Ich möchte es Unicode-kompatibel, deshalb kann ich [a-zA-Z] nicht verwenden.python-re: Wie passe ich ein Alpha-Zeichen an?

+1

"Unicode-kompatibel" - das bedeutet, dass Sie sowohl e übereinstimmen sollen und é, zum Beispiel? – Seth

+0

Denken Sie in Python daran, dass Sie eine Unicode-Zeichenfolge angeben müssen, die Sie verwenden müssen: u'Unicode string here '- vorausgesetzt, dass Sie versucht haben str.find() wo str ist Ihre Unicode-Zeichenfolge? – Alex

+3

Was ich meinte war, dass ich a, é, あ, 나 나, aber nicht 1, zuordnen wollte. (Punkt), 9, 9, usw. zum Beispiel. – basaundi

Antwort

42

Ihre ersten beiden Sätze widersprechen einander. "in \w ist aber nicht in \d" enthält Unterstrich. Ich gehe von deinem dritten Satz aus, dass du keinen Unterstrich willst.

Verwenden Sie ein Venn-Diagramm auf der Rückseite eines Umschlags hilft. Schauen wir uns an, was wir nicht wollen:

(1) Zeichen, die nicht durch \w abgestimmt sind (dh sie etwas nicht wollen, die nicht Alphas, Ziffern oder Unterstrich) =>\W
(2) Stellen = >\d
(3) = Strich>_

Also, was wir nicht wollen, etwas in der Zeichenklasse ist [\W\d_] und damit, was wir wollen tun, ist alles in der Zeichenklasse [^\W\d_]

Hier ist ein einfaches Beispiel (Python 2.6).

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

Weitere Explorations zeigt ein paar Macken dieses Ansatzes:

>>> 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) als numerische behandelt wird (daher passt es \ w), aber es scheint, dass Python interpretiert " digit“zu bedeuten "Dezimalziffer"(Kategorie Nd) so stimmt es nicht \ d

U + 2438 (eingekreist Kleines y) \ w

Alle CJK Ideogramme nicht übereinstimmen, werden eingestuft als "Buchstaben" und somit passend \ w

Ob einer der oben genannten 3 Punkte ein Problem ist oder nicht, dieser Ansatz ist der beste, den Sie aus dem re-Modul herausholen werden, wie es derzeit veröffentlicht wird. Syntax wie \ p {Buchstabe} ist in der Zukunft.

+0

Danke! Trotz der Macken, die du erwähnt hast, denke ich, ich kann von hier aus anfangen und sehen, was ich tunen kann. – basaundi

2

Was:

\p{L} 

Sie können dieses Dokument als Referenz verwenden: Unicode Regular Expressions

EDIT: Scheint Python doesn't handle Unicode expressions. Werfen Sie einen Blick in diesen Link: Handling Accented Characters with Python Regular Expressions -- [A-Z] just isn't good enough (nicht mehr aktiv, Link auf Internet-Archiv)

Weitere Referenzen:


Für Nachwelt, hier sind die Beispiele auf dem Blog:

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

Danke, aber ich kann nicht wissen, ob ein Zeichen ein (CJK) Interpunktionssymbol oder ein anderes numerisches Symbol als 0-9 ist, wenn ich einen Bereich wie \ u00e9- \ u00F8 mache. – basaundi

+1

können Sie mit Buchstabenbereichen arbeiten, wenn Sie auf ein Dokument wie http://www.tamasoft.co.jp/en/general-info/unicode.html verweisen und alle Buchstabenintervall auswählen (das könnte langweilig sein ...)); Dieser Link kann Ihnen auch helfen: http://kourge.net/projects/regexp-unicode-block –

+0

Ein Beispiel hierfür wäre hier hilfreich. –

0

Sie können eine der folgenden Ausdrücke verwenden, um einen einzelnen Buchstaben entsprechen:

(?![\d_])\w 

oder

\w(?<![\d_]) 

I für \w Hier passen, aber überprüfen, ob [\d_] nicht vor angepasst/danach .

Aus der Dokumentation:

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