Expression régulière insensible à la casse sans re.compile?

331

En Python, je peux compiler une expression régulière pour être insensible à la casse en utilisant 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>

Existe-t-il un moyen de faire de même, mais sans utiliser re.compile. Je ne trouve rien comme le isuffixe de Perl (par exemple m/test/i) dans la documentation.

Tapis
la source
1
Vous pouvez trouver une excellente introduction aux experssoins réguliers sur: python-course.eu/re.php
2Obe

Réponses:

562

Passez re.IGNORECASEà l' flagsPARAM search, matchou sub:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)
Michael Haren
la source
2
re.match('test', 'TeSt', re.IGNORECASE)peut conduire à l'un TypeErrorou l'autre des attributs None. Utiliser try & exceptpour attraper la TypeErrorcorrespondance par first_string == second_string. Exemple de code de 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 démonstration de code
Abhijeet
3
@Abhijeet Vous ne devriez vraiment pas utiliser try / sauf dans ce cas. Vérifiez simplement si l'une des chaînes est la Nonepremière.
erb
Il est important d'utiliser l'argument nommé flagspour re.subsinon il passe re.IGNORECASEà l' countargument (s aussi. Stackoverflow.com/questions/42581/...~~V~~singular~~3rd )
L3n95
101

Vous pouvez également effectuer des recherches insensibles à la casse en utilisant la recherche / correspondance sans l'indicateur IGNORECASE (testé en Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'
aem999
la source
2
La documentation ne mentionne pas la fonctionnalité ajoutée dans une version particulière (par opposition à, disons, (?(condition)yes|no)elle a été ajoutée en 2.4), donc je m'attends à ce qu'elle soit toujours disponible depuis la première version du remodule, qui, je pense, a été ajoutée en 1.5. Fondamentalement depuis le début des temps à toutes fins utiles en ce qui concerne Python. Il est documenté à mi-chemin de la première section de cette page: docs.python.org/2/library/re.html#regular-expression-syntax
ArtOfWarfare
4
C'est parti - j'ai parcouru la documentation de 1.5 et je l'ai trouvée documentée à environ 60% du bas de cette page: docs.python.org/release/1.5/lib/… J'ai également vérifié la documentation 1.4, qui ne faisait aucune mention de cette fonctionnalité. Je suppose donc qu'il a été ajouté en 1.5, lorsque le regexmodule a été déconseillé en faveur du remodule.
ArtOfWarfare
3
C'est une bonne solution car elle ne nécessite pas de drapeau. Dans mon cas, je stocke des chaînes de recherche dans Redis et cela est vraiment utile.
Privé le
3
@Private: conceptuellement, il définit le drapeau re.I sur toute l' expression régulière - pas seulement le groupe de capture qu'il précède. Sachez que cela re.match(r'''A ((?i)B) C''', "a b c").group(0)provoque une correspondance insensible à la casse sur tout (A et C), pas seulement sur B! Si vous ne voulez que la casse insensible sur un groupe de capture spécifique, ce n'est pas le droïde que vous recherchez.
smci
1
@ Privé: oui totalement. Mon point de vue est conceptuellement la même chose que la mise en place d'un drapeau. Sur toute l'expression régulière. Même les groupes qui le précèdent (!). Il n'y a pas de syntaxe pour dire "insensible à la casse sur les groupes de capture suivants uniquement".
smci
53

Le marqueur insensible à la casse (?i)peut être incorporé directement dans le motif d'expression régulière:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']
Raymond Hettinger
la source
2
Meilleure option, rend l'expression régulière portable sur toutes les plates-formes et l'intention est claire lors de la déclaration
Sina Madani
1
Cette '(?i)'approche présente également l'avantage que vous pouvez créer une liste d'expressions rationnelles, dont certaines ne respectent pas la casse et d'autres non. (Et bien sûr, vous pouvez cartographier re.compilecette liste si vous le souhaitez.)
not-just-yeti
@SinaMadani, je suis confus. Comment est-ce plus portable que flags=re.IGNORECASE?
Romain Vincent
10

Vous pouvez également définir la casse lors de la compilation du modèle:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
panofish
la source
5
Dans la question, OP l'utilise et demande s'il y a une autre façon de le faire.
Peter Wood
6
Utile pour ceux à défilement rapide.
stevek
6

Dans les importations

import re

En cours d'exécution:

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

Il convient de mentionner que ne pas utiliser re.compileest un gaspillage. Chaque fois que la méthode de correspondance ci-dessus est appelée, l'expression régulière est compilée. C'est également une pratique défectueuse dans d'autres langages de programmation. Ce qui suit est la meilleure pratique.

Dans l'initialisation de l'application:

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

En cours d'exécution:

if self.RE_TEST.match('TeSt'):
Douglas Daseeco
la source
1
Je vous remercie! Personne ne parle jamais de compilation, mais c'est l'option la plus intelligente!
StefanJCollier
2
L'OP demande littéralement une solution qui n'utilise ....re.compile()
wpercy
4
#'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
la source
4

Pour effectuer des opérations insensibles à la casse, fournissez re.IGNORECASE

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

et si nous voulons remplacer le texte correspondant à la casse ...

>>> 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'
Srivastava
la source
1

Si vous souhaitez remplacer tout en conservant le style de la chaîne précédente. C'est possible.

Par exemple: mettez en surbrillance la chaîne "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 Nguyen
la source
0

Pour l'expression régulière insensible à la casse (regex): Il existe deux façons d'ajouter votre code:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
  2. Le marqueur insensible à la casse (?i)

    Regx3GList = re.search("**(?i)**(WCDMA:)((\d*)(,?))*", txt)
Aliakbar Hosseinzadeh
la source