How do I use a regular expression to match a name?
I am a newbie in Python. I want to write a regular expression for some name checking. My input string can contain a-z, A-Z, 0-9, and ' _ ', but it should start with either a-z or A-Z (not 0-9 and ' _ '). I want to write a regular expression for this. I tried, but nothing was matching perfectly.
开发者_开发知识库Once the input string follows the regular expression rules, I can proceed further, otherwise discard that string.
Here's an answer to your question:
Interpreting that you want _
(not -
), this should do the job:
>>> 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
>>>
Stoutly resist the temptation to use $
; here's why:
Hello, hello, using $
is WRONG, use \Z
instead
>>> 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
The Fine Manual says:
'$'
Matches the end of the string or just before the newline at the end of the string [my emphasis], and in MULTILINE mode also matches before a newline. foo matches both ‘foo’ and ‘foobar’, while the regular expression foo$ matches only ‘foo’. More interestingly, searching for foo.$ in 'foo1\nfoo2\n' matches ‘foo2’ normally, but ‘foo1’ in MULTILINE mode; searching for a single $ in 'foo\n' will find two (empty) matches: one just before the newline, and one at the end of the string.
and
\Z
Matches only at the end of the string.
=== And now for something completely different ===
>>> 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
>>>
>>> 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")
>>>
Note: OP mentioned string cannot start from ( 0-9 and "_").
, apparently _ can be in the text. Thats why I am using \w
Note2: If you don't want match string ends with \n
, you could use \Z
instead of $
as John Machin mentioned.
here's a non re way
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
精彩评论