¿Expresión regular sin distinción entre mayúsculas y minúsculas sin recompilar?

331

En Python, puedo compilar una expresión regular para que no distinga entre mayúsculas y minúsculas usando 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>

¿Hay alguna manera de hacer lo mismo, pero sin usar re.compile? No puedo encontrar nada como el isufijo de Perl (por ejemplo m/test/i) en la documentación.

Estera
fuente
1
Puede encontrar una excelente introducción a los experssoins regulares en: python-course.eu/re.php
2Obe

Respuestas:

562

Pase re.IGNORECASEal flagsparámetro de search, matcho sub:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)
Michael Haren
fuente
2
re.match('test', 'TeSt', re.IGNORECASE)podría conducir a TypeErrorcuando cualquiera de los atributos es None. Utilizando try & exceptpara atrapar TypeErrorcoincidencias por first_string == second_string. Código de muestra Código 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 demostración
Abhijeet
3
@Abhijeet Realmente no deberías usar try / excepto en ese caso. Solo verifique si alguna de las cadenas es la Noneprimera.
erb
Es importante utilizar el argumento con nombre flagsporque de lo re.subcontrario pasa re.IGNORECASEal countargumento (también. Stackoverflow.com/questions/42581/… )
L3n95
101

También puede realizar búsquedas que no distinguen entre mayúsculas y minúsculas mediante la búsqueda / coincidencia sin el indicador IGNORECASE (probado en Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'
aem999
fuente
2
La documentación no menciona la característica que se agrega en ninguna versión en particular (en oposición a, por ejemplo, (?(condition)yes|no)que dice que se agregó en 2.4), por lo que espero que siempre haya estado disponible desde la primera versión del remódulo, que creo que se agregó en 1.5. Básicamente desde el principio de los tiempos para todos los efectos cuando se trata de Python. Está documentado a la mitad de la primera sección de esta página: docs.python.org/2/library/re.html#regular-expression-syntax
ArtOfWarfare
44
Aquí vamos. Revisé la documentación de 1.5 y encontré que estaba documentada aproximadamente el 60% de esta página: docs.python.org/release/1.5/lib/… También revisé la documentación de 1.4, que no mencionaba Esta característica. Así que supongo que se agregó en 1.5, cuando el regexmódulo quedó en desuso a favor del remódulo.
ArtOfWarfare 05 de
3
Esta es una buena solución ya que no requiere una bandera. En mi caso, estoy almacenando cadenas de búsqueda en Redis y esto es realmente útil.
Privado
3
@Private: conceptualmente establece el indicador re.I en toda la expresión regular, no solo en el grupo de captura que precede. Tenga en cuenta que esto re.match(r'''A ((?i)B) C''', "a b c").group(0)hace que las mayúsculas y minúsculas no coincidan en todo (A y C), ¡no solo en B! Si solo desea que las mayúsculas y minúsculas coincidan en un grupo de captura específico, este no es el droide que está buscando.
smci
1
@ Privado: sí totalmente. Mi punto conceptual es que es lo mismo que configurar una bandera. En toda la expresión regular. Incluso los grupos que lo preceden (!). No hay sintaxis para decir "no distingue entre mayúsculas y minúsculas en los siguientes grupos de captura solamente".
smci
53

El marcador que no distingue entre mayúsculas y minúsculas (?i)puede incorporarse directamente en el patrón de expresiones regulares:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']
Raymond Hettinger
fuente
2
Mejor opción, hace que el portátil de expresiones regulares en todas las plataformas y la intención es clara en la declaración
Sina Madani
1
Este '(?i)'enfoque también tiene la ventaja de que puede crear una lista de expresiones regulares, algunas de las cuales no distinguen entre mayúsculas y minúsculas y otras no. (Y, por supuesto, puede mapear re.compileesa lista si lo desea.)
not-just-yeti
@SinaMadani Estoy confundido. ¿Cómo es eso más portátil que flags=re.IGNORECASE?
Romain Vincent
10

También puede definir mayúsculas y minúsculas durante la compilación del patrón:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
panofish
fuente
55
En la pregunta, OP usa esto y pregunta si hay otra forma de hacerlo.
Peter Wood
66
Útil para los de desplazamiento rápido.
stevek
6

En importaciones

import re

En tiempo de ejecución de procesamiento:

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

Cabe mencionar que no usar re.compilees un desperdicio. Cada vez que se llama al método de coincidencia anterior, se compilará la expresión regular. Esto también es una práctica defectuosa en otros lenguajes de programación. La siguiente es la mejor práctica.

En la inicialización de la aplicación:

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

En tiempo de ejecución de procesamiento:

if self.RE_TEST.match('TeSt'):
Douglas Daseeco
fuente
1
¡Gracias! Nadie habla nunca de compilar, ¡pero es la opción más inteligente!
StefanJCollier
2
El OP literalmente pide una solución que no use 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
fuente
4

Para realizar operaciones que no distinguen entre mayúsculas y minúsculas, suministre re.IGNORECASE

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

y si queremos reemplazar el texto que coincida con el caso ...

>>> 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
fuente
1

Si desea reemplazar pero sigue manteniendo el estilo de str anterior. Es posible.

Por ejemplo: resalte la cadena "prueba 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)

prueba asdasd TEST asd tEst asdasd

Dat Nguyen
fuente
0

Para la expresión regular que no distingue entre mayúsculas y minúsculas (Regex): hay dos formas de agregar su código:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
  2. El marcador de mayúsculas y minúsculas (?i)

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