Espressione regolare senza distinzione tra maiuscole e minuscole senza re.compile?


331

In Python, posso compilare un'espressione regolare che non distingue tra maiuscole e minuscole 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>

C'è un modo per fare lo stesso, ma senza usare re.compile. Non riesco a trovare nulla come il isuffisso di Perl (ad esempio m/test/i) nella documentazione.


1
Puoi trovare un'eccellente introduzione agli experssoins regolari su: python-course.eu/re.php
2Obe

Risposte:


562

Passare re.IGNORECASEalla flagsparam di search, matcho sub:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)

2
re.match('test', 'TeSt', re.IGNORECASE)potrebbe portare a TypeErrorquando uno degli attributi è None. Utilizzare try & exceptper TypeErrorrilevare la corrispondenza con first_string == second_string. Codice 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 dimostrativo
Abhijeet

3
@Abhijeet Non dovresti davvero usare try / tranne in quel caso. Controlla se una delle stringhe è la Noneprima.
ERB

E 'importante utilizzare l'argomento di nome flagsper il re.subaltrimenti si passa re.IGNORECASEalla counttesi (s anche. Stackoverflow.com/questions/42581/...~~V~~singular~~3rd )
L3n95

101

Puoi anche eseguire ricerche senza distinzione tra maiuscole e minuscole utilizzando la ricerca / corrispondenza senza il flag IGNORECASE (testato in Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'

2
La documentazione non menziona la funzionalità aggiunta in una particolare versione (al contrario, dire (?(condition)yes|no)che dice che è stata aggiunta in 2.4), quindi mi aspetto che sia sempre stata disponibile dalla prima versione del remodulo, che penso sia stata aggiunta in 1.5. Fondamentalmente dall'inizio del tempo a tutti gli effetti quando si tratta di Python. È documentato a metà della prima sezione di questa pagina: docs.python.org/2/library/re.html#regular-expression-syntax
ArtOfWarfare

4
Eccoci qua: ho consultato la documentazione per 1.5 e l'ho trovata documentata circa il 60% in questa pagina: docs.python.org/release/1.5/lib/… Ho anche controllato la documentazione 1.4, che non ha menzionato questa caratteristica. Quindi suppongo che sia stato aggiunto in 1.5, quando il regexmodulo è stato deprecato a favore del remodulo.
ArtOfWarfare

3
Questa è una buona soluzione in quanto non richiede una bandiera. Nel mio caso sto memorizzando stringhe di ricerca in Redis e questo è davvero utile.
Privato

3
@Privato: concettualmente imposta il flag re.I sull'intera regex, non solo sul gruppo di acquisizione che precede. Tieni presente che re.match(r'''A ((?i)B) C''', "a b c").group(0)provoca una corrispondenza senza distinzione tra maiuscole e minuscole su tutto (A e C), non solo su B! Se desideri solo la corrispondenza tra maiuscole e minuscole su un gruppo di acquisizione specifico, questo non è il droide che stai cercando.
smci,

1
@Privato: si totalmente. Il mio punto è concettualmente che è lo stesso di impostare una bandiera. Su tutta la regex. Anche i gruppi che lo precedono (!). Non esiste una sintassi per dire "senza distinzione tra maiuscole e minuscole solo sui seguenti gruppi di acquisizione".
smci,

53

Il marcatore senza distinzione tra maiuscole e minuscole, (?i)può essere incorporato direttamente nel modello regex:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']

2
Opzione migliore, rende regex portatile su tutte le piattaforme e l'intenzione è chiara alla dichiarazione
Sina Madani,

1
Questo '(?i)'approccio ha anche il vantaggio di poter creare un elenco di regexp, alcuni dei quali non fanno distinzione tra maiuscole e minuscole e altri no. (E ovviamente, puoi mappare re.compilequell'elenco se vuoi.)
not-just-yeti

@SinaMadani Sono confuso. In che modo è più portatile di flags=re.IGNORECASE?
Romain Vincent,

10

È inoltre possibile definire la distinzione tra maiuscole e minuscole durante la compilazione del modello:

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

5
Nella domanda OP usa questo e chiede se c'è un altro modo per farlo.
Peter Wood,

6
Utile per quelli a scorrimento veloce.
stevek,

6

Nelle importazioni

import re

Nell'elaborazione del tempo di esecuzione:

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

Va detto che non usare re.compileè uno spreco. Ogni volta che viene chiamato il metodo di corrispondenza sopra, verrà compilata l'espressione regolare. Questa è anche una pratica errata in altri linguaggi di programmazione. Di seguito è la migliore pratica.

Nell'inizializzazione dell'app:

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

Nell'elaborazione del tempo di esecuzione:

if self.RE_TEST.match('TeSt'):

1
Grazie! Nessuno parla mai di compilazione, ma è l'opzione più intelligente!
StefanJCollier,

2
L'OP chiede letteralmente una soluzione che non usi 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'>

4

Per eseguire operazioni senza distinzione tra maiuscole e minuscole, fornire re.IGNORECASE

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

e se vogliamo sostituire il testo corrispondente al 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'

1

Se si desidera sostituire, mantenendo comunque lo stile della precedente str. È possibile.

Ad esempio: evidenziare la stringa "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


0

Per l'espressione regolare senza distinzione tra maiuscole e minuscole (Regex): Esistono due modi aggiungendo il codice:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
  2. Il marcatore senza distinzione tra maiuscole e minuscole (?i)

    Regx3GList = re.search("**(?i)**(WCDMA:)((\d*)(,?))*", txt)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.