2013/1/1 Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info>: > On Sun, 30 Dec 2012 10:20:19 -0500, Roy Smith wrote: > >> The way I would typically do something like this is build my regexes in >> all lower case and .lower() the text I was matching against them. I'm >> curious what you're doing where you want to enforce case sensitivity in >> one part of a header, but not in another. > > Well, sometimes you have things that are case sensitive, and other things > which are not, and sometimes you need to match them at the same time. I > don't think this is any more unusual than (say) wanting to match an > otherwise lowercase word whether or not it comes at the start of a > sentence: > > "[Pp]rogramming" > > is conceptually equivalent to "match case-insensitive `p`, and case- > sensitive `rogramming`". > > > By the way, although there is probably nothing you can (easily) do about > this prior to Python 3.3, converting to lowercase is not the right way to > do case-insensitive matching. It happens to work correctly for ASCII, but > it is not correct for all alphabetic characters. > > > py> 'Straße'.lower() > 'straße' > py> 'Straße'.upper() > 'STRASSE' > > > The right way is to casefold first, then match: > > py> 'Straße'.casefold() > 'strasse' > > > Curiously, there is an uppercase ß in old German. In recent years some > typographers have started using it instead of SS, but it's still rare, > and the official German rules have ß transform into SS and vice versa. > It's in Unicode, but few fonts show it: > > py> unicodedata.lookup('LATIN CAPITAL LETTER SHARP S') > 'ẞ' > > > > -- > Steven > -- > http://mail.python.org/mailman/listinfo/python-list
Hi, just for completeness, the mentioned regex library can take care of casfolding in case insensitive matching (in all supported versions: Python 2.5-2.7 and 3.1-3.3); i.e.: # case sensitive match: >>> for m in regex.findall(ur"Straße", u" STRAßE STRASSE STRAẞE Strasse Straße >>> "): print m ... Straße # case insensitive match: >>> for m in regex.findall(ur"(?i)Straße", u" STRAßE STRASSE STRAẞE Strasse >>> Straße "): print m ... STRAßE STRAẞE Straße # case insensitive match with casefolding: >>> for m in regex.findall(ur"(?if)Straße", u" STRAßE STRASSE STRAẞE Strasse >>> Straße "): print m ... STRAßE STRASSE STRAẞE Strasse Straße >>> >>> # after enabling the backwards incompatible modern matching behaviour, casefolding is by default turned on for case insensitive matches >>> for m in regex.findall(ur"(?V1i)Straße", u" STRAßE STRASSE STRAẞE Strasse >>> Straße "): print m ... STRAßE STRASSE STRAẞE Strasse Straße >>> As a small addition, the originally posted pattern r'^Msg-(?:(?i)id):' would actually work as expected in this modern matching mode in regex - enabled with the V1 flag. In this case the flag-setting (?i) only affects the following parts of the pattern, not the whole pattern like in the current "re" and V0-compatibility-mode "regex" >>> regex.findall(r"(?V1)Msg-(?:(?i)id):", "the regex should match Msg-id:, >>> Msg-Id:, ... but not msg-id:, MSG-ID: and so on") ['Msg-id:', 'Msg-Id:'] >>> regards, vbr -- http://mail.python.org/mailman/listinfo/python-list