Почему этот код регулярного выражения имеет разные результаты в Python 2.7 и Python 3.7? - PullRequest
3 голосов
/ 26 мая 2019

Это для проверки имени пользователя, мои коды:

import re
regex = r'^[\w.@+-]+\Z'
result = re.match(regex,'名字')

В python2.7 он возвращает None.

В python3.7 он возвращает '名字'.

1 Ответ

4 голосов
/ 26 мая 2019

Это из-за различных определений \w в Python 2.7 против Python 3.7.

В Python 2.7 имеем:

Если флаги LOCALE и UNICODE не указаны, соответствует любому буквенно-цифровой символ и подчеркивание; это эквивалентно набор [a-zA-Z0-9_].

(выделение, гиперссылка и форматирование добавлены)

Однако в Python 3.7 имеем:

Для шаблонов Unicode (str): соответствует символам слова Unicode; это включает в себя большинство символов, которые могут быть частью слова на любом языке, а также цифры и подчеркивание . Если используется флаг ASCII, только [a-zA-Z0-9_] соответствует.

(выделение и форматирование добавлены)

Итак, если вы хотите, чтобы он работал в обеих версиях, вы можете сделать что-то вроде этого:

# -*- coding: utf-8 -*-
import re
regex = re.compile(r'^[\w.@+-]+\Z', re.UNICODE)
match = regex.match(u'名字')

if match:
    print(match.group(0))
else:
    print("not matched!")

output:
名字

Вот доказательство того, что он работает в обеих версиях:

works

Обратите внимание на различия:

  • Я добавил # -*- coding: utf-8 -*- вверху скрипта, потому что без него в Python 2.7 мы получим ошибку , сказав

    Не-ASCII символ '\ xe5' в строке 3, но кодировка не объявлена; увидеть http://www.python.org/peps/pep-0263.html для подробностей

  • Вместо использования result = re.match(pattern, string) я использовал regex = re.compile(pattern, flags) и match = regex.match(string), чтобы я мог указать flags .

  • Я использовал флаг re.UNICODE, потому что без него в Python 2.7 он будет соответствовать [a-zA-Z0-9_] только при использовании \w.

  • Я использовал u'名字' вместо '名字', потому что в Python 2.7 вам нужно использовать Unicode Literal для символов Unicode.

Также, отвечая на ваш вопрос, я обнаружил, что print("not matched!") также работает в Python 2.7, что имеет смысл, потому что в этом случае скобки игнорируются, чего я не знал Так что это было весело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...