Python Regular Expressions - Complete Match
for my CGI application I'm writing a function to get the browser's preferred language (supplied in the HTTP_ACCEPT_LANGUAGE variable). I want to find all language tags in this variable with regular expressions (The general pattern of a language tag is defined in RFC1766). EBNF from RFC1766 ('1*8ALPHA' means one to eight ASCII chars):
Language-Tag = Primary-tag *( "-" Subtag )
Primary-tag = 1*8ALPHA
Subtag = 1*8ALPHA
I wrote this regular expression for a language tag:
(([a-z]{1,8})(-[a-z]{1,8})*)
If i use this expression, Python's re module supplies the following
>>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', '')]
The result is corre开发者_如何学JAVAct. But I only need complete matches like 'de-de' or 'x-pig-latin'. Can I assume that the first match of a group is always the most complete one? Or is there a flag telling re to show the most complete matches?
Stefan
You can use the ?: operator to prevent the regex engine from saving bracketed subpatterns:
((?:[a-z]{1,8})(?:-[a-z]{1,8})*)
This gives the output:
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']
To answer your question, the first match returned by findall should be the full matching substring.
Make your inner groups (i.e., parentheses) into non-capturing ones: that is, change from:
(([a-z]{1,8})(-[a-z]{1,8})*)
to:
((?:[a-z]{1,8})(?:-[a-z]{1,8})*)
To recap, the pattern notation (?: ... )
defines a non-capturing group: the parentheses stills serve the purpose of controlling priority, but don't leave traces in the match object's .groups()
and other capturing-group related traits.
Plain parentheses, ( ... )
, mean a capturing group.
There is no reason to use capturing groups for sub-matches that you're explicitly not interested about, of course. Use them only for the sub-matches you do care about!-)
Not sure if you've already checked it out, but this article has lots of good pointers about doing Accept-Language
parsing, along with a reference to a library that has already solved the problem.
As far as your re
question goes, Doug Hellman has a great breakdown of re
in his recent Python Module of the Week.
精彩评论