Как использовать регулярное выражение для сопоставления имени? - PullRequest
6 голосов
/ 23 февраля 2010

Я новичок в Python. Я хочу написать регулярное выражение для проверки имени. Моя входная строка может содержать a-z, A-Z, 0-9 и '_', но она должна начинаться с a-z или A-Z (не 0-9 и '_'). Я хочу написать регулярное выражение для этого. Я пытался, но ничего не подходило идеально.

Если входная строка соответствует правилам регулярных выражений, я могу продолжить, в противном случае отбросить эту строку.

Ответы [ 3 ]

6 голосов
/ 23 февраля 2010

Вот ответ на ваш вопрос:

Интерпретация, которую вы хотите _ (не -), это должно сделать работу:

>>> 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

В «Руководстве по тонкой настройке» написано:

'$'
Соответствует концу строки или непосредственно перед новой строкой в ​​конце строки [мой акцент], а в режиме MULTILINE также соответствует перед новой строкой. foo совпадает как с «foo», так и с «foobar», а регулярное выражение foo $ соответствует только «foo». Что еще интереснее, поиск foo. $ В 'foo1 \ nfoo2 \ n' обычно соответствует 'foo2', но 'foo1' в режиме MULTILINE; при поиске одного $ в '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
>>>
4 голосов
/ 23 февраля 2010
>>> 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")
>>>

Примечание : упомянутый ОП string cannot start from ( 0-9 and "_")., по-видимому, _ может быть в тексте. Вот почему я использую \w

Примечание2 : Если вы не хотите, чтобы совпадающая строка заканчивалась на \n, вы можете использовать \Z вместо $, как упоминал Джон Мачин.

0 голосов
/ 23 февраля 2010

вот не повторный путь

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...