ChatGPT解决这个技术问题 Extra ChatGPT

Case insensitive regular expression without re.compile?

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.

You can find an excellent introduction to regular experssoins at: python-course.eu/re.php

M
Mark Amery

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)

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
@Abhijeet You really shouldn't use try/except in that case. Just check if any of the strings are None first.
It's important to use the named argument flags for re.sub otherwise it passes re.IGNORECASE to the count argument (s. also stackoverflow.com/questions/42581/…)
or: re.I shorthand.
a
aem999

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'

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: docs.python.org/2/library/re.html#regular-expression-syntax
Here we go - I looked through the documentation for 1.5 and found it documented about 60% of the way down this page: docs.python.org/release/1.5/lib/… 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.
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: 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 I think this should be edited in the answer itself.
R
Raymond Hettinger

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']

Better option, makes the regex portable across platforms and intent is clear at declaration
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.)
@SinaMadani I'm confused. How is that more portable than flags=re.IGNORECASE?
@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.
@RoboRobok Ah yes, I didn't think about it this way. Thank you for your reply!
M
Mark Amery

You can also define case insensitive during the pattern compile:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)

In the question OP uses this and asks whether there's another way to do it.
Helpful for the fast-scrolling ones.
w
wpercy

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'):

Thank you! No one ever talks about compile, yet it's the smartest option!
The OP literally asks for a solution that doesn't use re.compile()....
t
this.srivastava

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'

P
Paul Roub

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

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


j
jackotonye
#'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'>

D
Dat

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