534

In Python, I can compile a regular expression to be case-insensitive using re.compile:

>>> s = 'TeSt'
>>> casesensitive = re.compile('test')
>>> ignorecase = re.compile('test', re.IGNORECASE)
>>> 
>>> print casesensitive.match(s)
None
>>> print ignorecase.match(s)
<_sre.SRE_Match object at 0x02F0B608>

Is there a way to do the same, but without using re.compile. I can't find anything like Perl's i suffix (e.g. m/test/i) in the documentation.

martineau
  • 119,623
  • 25
  • 170
  • 301
Mat
  • 82,161
  • 34
  • 89
  • 109
  • 3
    You can find an excellent introduction to regular experssoins at: http://www.python-course.eu/re.php – 2Obe Jul 22 '17 at 07:40

10 Answers10

830

Pass re.IGNORECASE to the flags param of search, match, or sub:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Michael Haren
  • 105,752
  • 40
  • 168
  • 205
  • 4
    `re.match('test', 'TeSt', re.IGNORECASE)` might lead to `TypeError` when either of the attribute being `None`. Using `try & except` to catch `TypeError` matching by first_string == second_string. **Sample Code** `def equal_ignore_case(first_string, second_string): try: return re.match(first_string, second_string, re.IGNORECASE) is not None except (AttributeError, TypeError): return first_string == second_string` [Demo Code](https://repl.it/FWih) – Abhijeet Jan 27 '17 at 02:57
  • 10
    @Abhijeet You really shouldn't use try/except in that case. Just check if any of the strings are `None` first. – erb Oct 21 '19 at 05:56
  • 10
    It's important to use the named argument `flags` for `re.sub` otherwise it passes `re.IGNORECASE` to the `count` argument (s. also https://stackoverflow.com/questions/42581/python-re-sub-with-a-flag-does-not-replace-all-occurrences) – L3n95 Jan 15 '20 at 07:46
  • 2
    or: `re.I` shorthand. – meni181818 Jan 24 '22 at 09:35
  • Older versions of re have to use RegexFlag to access IGNORECASE. e.x.: `re.RegexFlag.IGNORECASE` – Jim Fell Jul 27 '23 at 23:15
152

You can also perform case insensitive searches using search/match without the IGNORECASE flag (tested in Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'
aem999
  • 16,923
  • 4
  • 22
  • 12
  • 2
    The documentation doesn't mention the feature being added in any particular version (as opposed to, say `(?(condition)yes|no)` which it says was added in 2.4), so I expect it has always been available since the first version of the `re` module, which I think was added in 1.5. Basically since the beginning of time for all intents and purposes when it comes to Python. It's documented about half way through the first section of this page: https://docs.python.org/2/library/re.html#regular-expression-syntax – ArtOfWarfare May 05 '15 at 18:24
  • 5
    Here we go - I looked through the documentation for 1.5 and found it documented about 60% of the way down this page: https://docs.python.org/release/1.5/lib/node65.html#SECTION005210000000000000000 I also checked the 1.4 documentation, which made no mention of this feature. So I guess it was added in 1.5, when the `regex` module was deprecated in favor of the `re` module. – ArtOfWarfare May 05 '15 at 18:30
  • 3
    This is a nice solution as it does not require a flag. In my case I am storing search strings in Redis and this is really helpful. – Private Sep 08 '16 at 16:09
  • For instance `[st for st in filter(lambda x: not search(r'(?i)Mac', x), ['macintosh','tomato','MacMahon', 'and', 'maCaroni', 'pasta'])]` will filter out all those [Mm][Aa][Cc] matches and only leave us with `['tomato', 'and', 'pasta']` – rloth Oct 06 '16 at 22:15
  • 5
    @Private: conceptually it does set the re.I flag on the *entire* regex - not just the capture group it precedes. Be aware that `re.match(r'''A ((?i)B) C''', "a b c").group(0)` causes case-insensitive matching on everything (A and C), not just on B! If you only want case-insens matching on a specific capture group, this isn't the droid you're looking for. – smci Dec 04 '17 at 21:33
  • 2
    @Private: yes totally. My point is conceptually it's the same as setting a flag. On the entire regex. Even the groups that precede it(!). There is no syntax to say "case-insensitive on the following capture groups only". – smci Dec 05 '17 at 14:04
  • 2
    @smci I think this should be edited in the answer itself. – Private Dec 06 '17 at 18:29
92

The case-insensitive marker, (?i) can be incorporated directly into the regex pattern:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • 8
    Better option, makes the regex portable across platforms and intent is clear at declaration – Sina Madani Nov 23 '17 at 17:14
  • 6
    This `'(?i)'` approach also has the advantage that you can create a list of regexp's, some of which are case-insensitive and some are not. (And of course, you can map `re.compile` over that list if you like.) – not-just-yeti Sep 01 '19 at 22:20
  • @SinaMadani I'm confused. How is that more portable than `flags=re.IGNORECASE`? – Romain Vincent Mar 19 '20 at 14:14
  • 2
    @RomainVincent more portable as you can just copy-paste the pattern itself and use it somewhere else. I'm not yet sure if I like this approach though. – Robo Robok Sep 09 '20 at 12:08
  • @RoboRobok Ah yes, I didn't think about it this way. Thank you for your reply! – Romain Vincent Sep 18 '20 at 16:27
25

You can also define case insensitive during the pattern compile:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
panofish
  • 7,578
  • 13
  • 55
  • 96
16

In imports

import re

In run time processing:

RE_TEST = r'test'
if re.match(RE_TEST, 'TeSt', re.IGNORECASE):

It should be mentioned that not using re.compile is wasteful. Every time the above match method is called, the regular expression will be compiled. This is also faulty practice in other programming languages. The below is the better practice.

In app initialization:

self.RE_TEST = re.compile('test', re.IGNORECASE)

In run time processing:

if self.RE_TEST.match('TeSt'):
wpercy
  • 9,636
  • 4
  • 33
  • 45
Douglas Daseeco
  • 3,475
  • 21
  • 27
13

To perform case-insensitive operations, supply re.IGNORECASE

>>> import re
>>> test = 'UPPER TEXT, lower text, Mixed Text'
>>> re.findall('text', test, flags=re.IGNORECASE)
['TEXT', 'text', 'Text']

and if we want to replace text matching the case...

>>> def matchcase(word):
        def replace(m):
            text = m.group()
            if text.isupper():
                return word.upper()
            elif text.islower():
                return word.lower()
            elif text[0].isupper():
                return word.capitalize()
            else:
                return word
        return replace

>>> re.sub('text', matchcase('word'), test, flags=re.IGNORECASE)
'UPPER WORD, lower word, Mixed Word'
this.srivastava
  • 1,045
  • 12
  • 22
10

For Case insensitive regular expression(Regex): There are two ways by adding in your code:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, re.IGNORECASE)
    
  2. The case-insensitive marker (?i)

    Regx3GList = re.search("**(?i)**(WCDMA:)((\d*)(,?))*", txt)
    
Nuno André
  • 4,739
  • 1
  • 33
  • 46
5
#'re.IGNORECASE' for case insensitive results short form re.I
#'re.match' returns the first match located from the start of the string. 
#'re.search' returns location of the where the match is found 
#'re.compile' creates a regex object that can be used for multiple matches

 >>> s = r'TeSt'   
 >>> print (re.match(s, r'test123', re.I))
 <_sre.SRE_Match object; span=(0, 4), match='test'>
 # OR
 >>> pattern = re.compile(s, re.I)
 >>> print(pattern.match(r'test123'))
 <_sre.SRE_Match object; span=(0, 4), match='test'>
jackotonye
  • 3,537
  • 23
  • 31
4

If you would like to replace but still keeping the style of previous str. It is possible.

For example: highlight the string "test asdasd TEST asd tEst asdasd".

sentence = "test asdasd TEST asd tEst asdasd"
result = re.sub(
  '(test)', 
  r'<b>\1</b>',  # \1 here indicates first matching group.
  sentence, 
  flags=re.IGNORECASE)

test asdasd TEST asd tEst asdasd

Dat
  • 5,405
  • 2
  • 31
  • 32
0

(?i) match the remainder of the pattern with the following effective flags: i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])

>>> import pandas as pd
>>> s = pd.DataFrame({ 'a': ["TeSt"] })
>>> r = s.replace(to_replace=r'(?i)test', value=r'TEST', regex=True)
>>> print(r)
      a
0  TEST
Ax_
  • 803
  • 8
  • 11