Регулярное выражение номера телефона Python работает недостаточно хорошо

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

pattern = re.compile('\d{3,4}(\/?)(\d{6,6})')
m= pattern.match('0481/987421')
if m:
    print "yes"
else:
    print "no"

Это регулярное выражение должно работать для телефонных номеров следующим образом: dddd/dddddddd, то есть сначала 3 или 4 цифры, затем косая черта или нет, а затем ровно 6 цифр. Работает нормально, например 21/484135 не работает и другие неправильные вещи тоже не работают. Но проблема этого регулярного выражения в том, что когда мои первые символы верны, и я набираю за ним что-то случайное, оно все равно печатает «да». Я имею в виду что-то вроде этого: 0481/9874214879516874 Я думаю, что, поскольку регулярное выражение соответствует первым 11 символам, оно возвращает совпадение, и не имеет значения, что за ним стоит.

Как я могу решить эту проблему?


person Confituur    schedule 14.03.2012    source источник
comment
Я знаю, что это может показаться не по теме, но... что это за телефонные номера это?   -  person Droogans    schedule 15.03.2012
comment
Ах... этот \d{3, 4} действительно меня запутал. Тем временем кто-то разместил якорь $. Вы, вероятно, должны проголосовать за них сейчас.   -  person Droogans    schedule 15.03.2012


Ответы (2)


Вам нужно закрепить свое выражение. Добавьте $ или \Z в конце, чтобы убедиться, что за ним ничего не следует. Вы также можете добавить ^, чтобы привязать его к началу строки, хотя это не требуется при использовании с match().

pattern = re.compile(r"^\d{3,4}/?\d{6}\Z")
person Qtax    schedule 14.03.2012
comment
о нет, когда я удаляю косую черту, она больше не совпадает :/ - person Confituur; 15.03.2012
comment
вы используете ту же версию Python? - person przemo_li; 15.03.2012
comment
Python использует заглавную \Z (в то время как другие используют строчные буквы \z), исправлено. См. рабочий пример на странице ideone. - person Qtax; 15.03.2012

Я бы предложил использовать модуль phonenumbers вместо написания собственного регулярного выражения. Вот пример разбора бельгийского номера телефона:

>>> x = phonenumbers.parse("0481/987421", "BE")
>>> x
PhoneNumber(country_code=32,
            national_number=481987421L,
            extension=None,
            italian_leading_zero=False,
            country_code_source=None,
            preferred_domestic_carrier_code=None)

Это вызовет исключение для недопустимых телефонных номеров:

>>> x = phonenumbers.parse("0481/9874214879516874", "BE")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/phonenumbers/phonenumberutil.py", line 2038, in parse
    "The string supplied is too long to be a phone number.")
phonenumbers.phonenumberutil.NumberParseException: (4) The string supplied is too long to be a phone number.
person jterrace    schedule 14.03.2012