python-re:如何匹配字母字符 [英] python-re: How do I match an alpha character

查看:167
本文介绍了python-re:如何匹配字母字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将字母字符与正则表达式匹配.我想要一个位于 \w 但不在 \d 中的字符.我希望它与 unicode 兼容,这就是为什么我不能使用 [a-zA-Z].

解决方案

你的前两句话相互矛盾.在 \w 中但不在 \d 中"包括下划线.我从你的第三句话假设你不想要下划线.

使用信封背面的维恩图会有所帮助.让我们看看我们不想要什么:

(1) 与 \w 不匹配的字符(即不想要任何非字母、数字或下划线)=> \W
(2) 数字 => \d
(3) 下划线 => _

所以我们不想要字符类 [\W\d_] 中的任何东西,因此我们想要的是字符类 [^\W\d_ 中的任何东西]

这是一个简单的例子(Python 2.6).

<预><代码>>>>进口重新>>>rx = re.compile("[^\W\d_]+", re.UNICODE)>>>rx.findall(u"abc_def,k9")[u'abc', u'def', u'k']

进一步的探索揭示了这种方法的一些怪癖:

<预><代码>>>>将 unicodedata 导入为 ucd>>>allsorts =u"\u0473\u0660\u06c9\u24e8\u4e0a\u3020\u3021">>>对于各种类型的 x:... 打印 repr(x), ucd.category(x), ucd.name(x)...u'\u0473' Ll 西里尔小写字母 FITAu'\u0660' Nd 阿拉伯-印度数字零u'\u06c9' Lo 阿拉伯字母 KIRGHIZ YUu'\u24e8' 如此圈出的拉丁文小写字母 Yu'\u4e0a' Lo CJK UNIFIED IDEOGRAPH-4E0Au'\u3020' 所以邮政标志的脸u'\u3021' Nl 杭州数字一>>>rx.findall(各种)[u'\u0473'、u'\u06c9'、u'\u4e0a'、u'\u3021']

U+3021(杭州数字一)被视为数字(因此它匹配 \w)但似乎 Python 将数字"解释为十进制数字"(类别 Nd),因此它不匹配 \d

U+2438(带圆圈的拉丁文小写字母 Y)与 \w 不匹配

所有 CJK 表意文字都被归类为字母",因此匹配 \w

无论以上 3 点中的任何一个是否值得关注,这种方法都是您从当前发布的 re 模块中获得的最佳方法.像 \p{letter} 这样的语法是未来的.

How can I match an alpha character with a regular expression. I want a character that is in \w but is not in \d. I want it unicode compatible that's why I cannot use [a-zA-Z].

解决方案

Your first two sentences contradict each other. "in \w but is not in \d" includes underscore. I'm assuming from your third sentence that you don't want underscore.

Using a Venn diagram on the back of an envelope helps. Let's look at what we DON'T want:

(1) characters that are not matched by \w (i.e. don't want anything that's not alpha, digits, or underscore) => \W
(2) digits => \d
(3) underscore => _

So what we don't want is anything in the character class [\W\d_] and consequently what we do want is anything in the character class [^\W\d_]

Here's a simple example (Python 2.6).

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

Further exploration reveals a few quirks of this approach:

>>> 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) is treated as numeric (hence it matches \w) but it appears that Python interprets "digit" to mean "decimal digit" (category Nd) so it doesn't match \d

U+2438 (CIRCLED LATIN SMALL LETTER Y) doesn't match \w

All CJK ideographs are classed as "letters" and thus match \w

Whether any of the above 3 points are a concern or not, that approach is the best you will get out of the re module as currently released. Syntax like \p{letter} is in the future.

这篇关于python-re:如何匹配字母字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆