2010-09-08 7 views
1

для моего приложения CGI. Я пишу функцию, чтобы получить предпочтительный язык браузера (указанный в переменной HTTP_ACCEPT_LANGUAGE). Я хочу найти все языковые метки в этой переменной с регулярными выражениями (общий шаблон языкового тега определен в RFC1766). EBNF из RFC1766 ('1 * 8ALPHA' означает, что один на восемь ASCII символов):Регулярные выражения Python - Полное совпадение

Language-Tag = Primary-tag *("-" Subtag) 
Primary-tag = 1*8ALPHA 
Subtag = 1*8ALPHA 

Я написал это регулярное выражение для тега языка:

(([a-z]{1,8})(-[a-z]{1,8})*) 

Если я использую это выражение, повторно модуль питона поставляет следующие

>>import re 

>>re.findall("(([a-z]{1,8})(-[a-z]{1,8})*)", "x-pig-latin en-us de-de en", re.IGNORECASE) 
[('x-pig-latin', 'x', '-latin'), ('en-us', 'en', '-us'), ('de-de', 'de', '-de'), ('en', 'en', '')] 

Результат правильный. Но мне нужны только полные матчи, такие как de-de или x-pig-latin. Могу ли я предположить, что первое совпадение группы всегда самое полное? Или есть флаг, показывающий re, чтобы показать самые полные матчи?

Стефан

ответ

0

Не уверен, что если вы уже проверили это, но this article имеет много хороших указатели о делать Accept-Language синтаксическими, а также ссылки на библиотеку, которая уже решила проблему.

Что касается вашего вопроса re, у Doug Hellman есть great breakdown of re в его последнем модуле Python недели.

4

Вы можете использовать оператор?: Чтобы предотвратить регулярки двигателя от экономии в квадратных скобках подшаблонов:

((?:[a-z]{1,8})(?:-[a-z]{1,8})*) 

Это дает выход:

re.findall("((?:[a-z]{1,8})(?:-[a-z]{1,8})*)", "x-pig-latin en-us de-de en", re.IGNORECASE) 
['x-pig-latin', 'en-us', 'de-de', 'en'] 

Чтобы ответить на ваш вопрос, первый матч, возвращенный findall должна быть полной совпадающей подстрокой.

+0

Спасибо, это именно то, что я ищу. Я никогда раньше не использовал оператор?:. – Stefan

2

сделать ваши внутренние группы (т.е. круглые скобки) в , не являющихся -capturing из них: то есть, переход от:

(([a-z]{1,8})(-[a-z]{1,8})*) 

к:

((?:[a-z]{1,8})(?:-[a-z]{1,8})*) 

Напомним, что картина обозначения (?: ...) определяет , но не. Группа захвата: круглые скобки служат для управления приоритетом, но не оставляют следы в объекте совпадения .groups() и другие связанные с захватом группы черты.

Обычные круглые скобки, (...), a a улов группа.

Нет причин использовать группы захвата для вспомогательных матчей, которые вы явно не заинтересованы, конечно. Используйте их только для вспомогательных матчей. do Осторожно! -)

Смежные вопросы