如何使用正则表达式匹配姓名?

6 投票
3 回答
3675 浏览
提问于 2025-04-15 19:37

我刚开始学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
>>>

撰写回答