如何使用正则表达式匹配姓名?
我刚开始学Python,想写一个正则表达式来检查名字。我的输入字符串可以包含小写字母a-z、大写字母A-Z、数字0-9,还有下划线' _ ',但是它必须以小写字母或大写字母开头,不能以数字或下划线开头。我想为这个规则写一个正则表达式。我试过了,但总是匹配不太好。
一旦输入字符串符合正则表达式的规则,我就可以继续处理,否则就把这个字符串丢掉。
3 个回答
-1
这里有一种不使用正则表达式的方法
import string
flag=0
mystring="abcadsf123"
if not mystring[0] in string.digits+"_":
for c in mystring:
if not c in string.letters+string.digits+"-":
flag=1
if flag: print "%s not ok" % mystring
else: print "%s ok" % mystring
else: print "%s starts with digits or _" % mystring
4
>>> import re
>>> re.match("[a-zA-Z][\w-]*$","A")
<_sre.SRE_Match object at 0x00932E20>
>>> re.match("[a-zA-Z][\w-]*$","A_B")
<_sre.SRE_Match object at 0x008CA950>
>>> re.match("[a-zA-Z][\w-]*$","0A")
>>>
>>> re.match("[a-zA-Z][\w-]*$","!A_B")
>>>
注意: 原作者提到 字符串不能以 (0-9 和 "_") 开头。
,显然 "_" 可以出现在文本中。所以我使用了 \w
。
注意2: 如果你不想匹配以 \n
结尾的字符串,可以像 John Machin 提到的那样,用 \Z
替代 $
。
7
这是对你问题的回答:
如果你想要的是 _
(而不是 -
),那么可以试试这个:
>>> tests = ["a", "A", "a1", "a_1", "1a", "_a", "a\n", "", "z_"]
>>> for test in tests:
... print repr(test), bool(re.match(r"[A-Za-z]\w*\Z", test))
...
'a' True
'A' True
'a1' True
'a_1' True
'1a' False
'_a' False
'a\n' False
'' False
'z_' True
>>>
一定要抵制使用 $
的诱惑;原因如下:
你好,使用 $
是错误的,应该用 \Z
来代替
>>> re.match(r"[a-zA-Z][\w-]*$","A")
<_sre.SRE_Match object at 0x00BAFE90>
>>> re.match(r"[a-zA-Z][\w-]*$","A\n")
<_sre.SRE_Match object at 0x00BAFF70> # WRONG; SHOULDN'T MATCH
>>>
>>> re.match(r"[a-zA-Z][\w-]*\Z","A")
<_sre.SRE_Match object at 0x00BAFE90>
>>> re.match(r"[a-zA-Z][\w-]*\Z","A\n")
>>> # CORRECT: NO MATCH
官方手册上说:
'$'
匹配字符串的结尾或者在字符串结尾的换行符之前(我强调一下),而在多行模式下也会匹配换行符之前的地方。比如,'foo' 可以匹配 'foo' 和 'foobar',但正则表达式 foo$ 只匹配 'foo'。更有趣的是,在 'foo1\nfoo2\n' 中搜索 foo.$ 会正常匹配 'foo2',但在多行模式下会匹配 'foo1';在 'foo\n' 中搜索单个 $ 会找到两个(空的)匹配:一个是在换行符之前,另一个是在字符串的结尾。
还有
\Z
只匹配字符串的结尾。
=== 现在换个话题 ===
>>> import string
>>> letters = set(string.ascii_letters)
>>> ok_chars = letters | set(string.digits + "_")
>>>
>>> def is_valid_name(strg):
... return strg and strg[0] in letters and all(c in ok_chars for c in strg)
...
>>> for test in tests:
... print repr(test), repr(is_valid_name(test))
...
'a' True
'A' True
'a1' True
'a_1' True
'1a' False
'_a' False
'a\n' False
'' ''
'z_' True
>>>