tags:

views:

2729

answers:

5

I've seen lots of examples of making an entire regular expression case-insensitive. What I'm wondering about is having just part of the expression be case-insensitive.

For example, let's say I have a string like this:

fooFOOfOoFoOBARBARbarbarbAr

What if I want to match all occurrences of "foo" regardless of case but I only want to match the upper-case "BAR"s?

The ideal solution would be something that works across regex flavors but I'm interested in hearing language-specific ones as well (Thanks Espo)

Edit

The link Espo provided was very helpful. There's a good example in there about turning modifiers on and off within the expression.

For my contrived example, I can do something like this:

(?i)foo*(?-i)|BAR

which makes the match case-insensitive for just the foo portion of the match.

That seemed to work in most regex implementations except Javascript, Python, and a few others (as Espo mentioned).

The big ones that I was wondering about (Perl, PHP, .NET) all support inline mode changes.

+13  A: 

Perl lets you make part of your regular expression case-insensitive by using the (?i:) pattern modifier.

Modern regex flavors allow you to apply modifiers to only part of the regular expression. If you insert the modifier (?ism) in the middle of the regex, the modifier only applies to the part of the regex to the right of the modifier. You can turn off modes by preceding them with a minus sign. All modes after the minus sign will be turned off. E.g. (?i-sm) turns on case insensitivity, and turns off both single-line mode and multi-line mode.

Not all regex flavors support this. JavaScript and Python apply all mode modifiers to the entire regular expression. They don't support the (?-ismx) syntax, since turning off an option is pointless when mode modifiers apply to the whole regular expressions. All options are off by default.

You can quickly test how the regex flavor you're using handles mode modifiers. The regex (?i)te(?-i)st should match test and TEst, but not teST or TEST.

Source

Espo
+2  A: 

You could use

(?:F|f)(?:O|o)(?:O|o)

The ?: in the brackets in .Net means it's non-capturing, and just used to group the terms of the | (or) statement.

Kibbee
Isn't "[fF][oO][oO]" the better alternative? For the example at hand you could even go as far as "[fF][oO]\{2}" ;-)
Tomalak
A: 

.Net also allows case insensite sections using (?i:)

Kibbee
+1  A: 

What language are you using? A standard way to do this would be something like /([Ff][Oo]{2}|BAR)/ with case sensitivity on, but in Java, for example, there is a case sensitivity modifier (?i) which makes all characters to the right of it case insensitive and (?-i) which forces sensitivity. An example of that Java regex modifier can be found here.

akdom
+1 Why bother making it case insensitive when you can match both cases
Nona Urbiz
+1  A: 

Unfortunately syntax for case-insensitive matching is not common. In .NET you can use RegexOptions.IgnoreCase flag or ?i modifier

aku