Проверка цельной строки с помощью регулярного выражения

Я пытаюсь проверить, является ли строка числом, поэтому регулярное выражение "\ d +" показалось хорошим. Однако это регулярное выражение также подходит по "78.46.92.168:8000" по какой-то причине, чего я не хочу, немного кода:

class Foo():
    _rex = re.compile("\d+")
    def bar(self, string):
         m = _rex.match(string)
         if m != None:
             doStuff()

И вызывается doStuff() при вводе IP-адреса. Я немного смущен, как это происходит ". или": "соответствуют" \ d"?

Ответ 1

\d+ соответствует любому положительному числу цифр внутри вашей строки, поэтому оно соответствует первому 78 и преуспевает.

Используйте ^\d+$.

Или еще лучше: "78.46.92.168:8000".isdigit()

Ответ 2

re.match() всегда совпадает с началом строки (в отличие от re.search()), но позволяет завершить матч до конца строки.

Следовательно, вам нужен якорь: _rex.match(r"\d+$") будет работать.

Чтобы быть более явным, вы также можете использовать _rex.match(r"^\d+$") (который является избыточным) или просто отбросить re.match() вообще и просто использовать _rex.search(r"^\d+$").

Ответ 3

\Z соответствует концу строки, а $ соответствует концу строки или непосредственно перед новой строкой в ​​конце строки и демонстрирует различное поведение в re.MULTILINE. Подробнее см. документацию по синтаксису.

>>> s="1234\n"
>>> re.search("^\d+\Z",s)
>>> s="1234"
>>> re.search("^\d+\Z",s)
<_sre.SRE_Match object at 0xb762ed40>

Ответ 4

Измените его с \d+ на ^\d+$

Ответ 5

В Python есть пара опций для соответствия целому вводу с регулярным выражением.

Python 2

В Python 2.x вы можете использовать

re.match(r'\d+$') # re.match anchors the match at the start of the string, so $ is what remains to add

или - чтобы избежать сопоставления перед окончательным \n в строке:

re.match(r'\d+\Z') # \Z will only match at the very end of the string

Или то же, что указано выше, с помощью метода re.search, требующего использования привязки ^/\A начала строки, поскольку он не привязывает соответствие в начале строки:

re.search(r'^\d+$')
re.search(r'\A\d+\Z')

Обратите внимание, что \A является однозначным началом начала строки, его поведение не может быть переопределено с помощью каких-либо модификаторов (re.M/re.MULTILINE может только переопределить поведение ^ и $).

Python 3

Все те случаи, которые описаны в разделе Python 2 и еще один полезный метод, re.fullmatch (также присутствуют в PyPi regex модуль):

Если вся строка соответствует шаблону регулярного выражения, верните соответствующий объект соответствия. Возвращает None, если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.

Итак, после компиляции регулярного выражения просто используйте соответствующий метод:

_rex = re.compile("\d+")
if _rex.fullmatch(s):
    doStuff()