2007 Oct 27th
がわかっていなかったことがわかってなんだかがっくりきたという話。

aaa TARGET xxx
だったり
aaa DUMMY bbb TARGET yyy xxx
だったりすることがある文字列から TARGET を取り出したいというシチュエーションで、
re.compile('bbb (.*?) yyy|aaa (.*?) xxx')
を使っていました。対象としている文字列がどちらの場合でも、 "bbb (.*?) yyy" が先にマッチして TARGET が抜き出せると思っていたのです。
ところがどっこいこれは間違いで、この結果は
>>> s = 'aaa DUMMY bbb TARGET yyy xxx'
>>> p = re.compile('bbb (.*?) yyy|aaa (.*?) xxx')
>>> p.search(s).groups()
(None, 'DUMMY bbb TARGET yyy')
となるのです。
kharakawa に相談したところ、正規表現オブジェクトが s を評価すると、まず aaa の部分がマッチしてそのまま評価を続け、 xxx まで進んで最終的に "aaa (.*?) xxx" にマッチするんだというようなことを教わりました。なので、例えば明示的に
>>> p = re.compile('bbb (.*?) yyy|aaa (?!bbb) (.*?) xxx')
とするのも手なのかもしれません。でもこれだと内包するようなケースが増えると書くのもしんどいし、後で見る人もしんどいので、
>>> pats = [re.compile('bbb (.*?) yyy'), re.compile('aaa (.*?) xxx')]
>>> for pat in pats:
...   searched = pat.search(s)
...   if searched:
...     searched.groups()
...     break
... 
('TARGET',)
みたいにした方が良いかなと思いました。ちょっとあほっぽいような気もしなくもないけど。
Posted by setomits at 12:21 | Comments: 0
Leave a comment
Required fields are marked with *
search
calendar
Jul 2010
SunMonTueWedThuFriSat
    123
45678910
11121314151617
18192021222324
25262728293031
archives
photos on flickr
www.flickr.com
bookmarks on delicious