Expressão regular que não diferencia maiúsculas de minúsculas sem re.compilar?

331

No Python, eu posso compilar uma expressão regular para não diferenciar maiúsculas de 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>

Existe uma maneira de fazer o mesmo, mas sem usar re.compile. Não consigo encontrar nada como o isufixo do Perl (por exemplo m/test/i) na documentação.

Esteira
fonte
1
Você pode encontrar uma excelente introdução às expansões regulares em: python-course.eu/re.php
2Obe

Respostas:

562

Passe re.IGNORECASEpara o flagsparam de 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
fonte
2
re.match('test', 'TeSt', re.IGNORECASE)pode levar a TypeErrorquando um dos atributos está None. Usando try & exceptpara capturar a TypeErrorcorrespondência first_string == second_string. Exemplo de Código 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
3
@Abhijeet Você realmente não deve usar try /, exceto nesse caso. Basta verificar se alguma das strings é a Noneprimeira.
erb
É importante usar o argumento nomeado flagspara re.subcaso contrário, passa re.IGNORECASEao countargumento (s também. Stackoverflow.com/questions/42581/... )
L3n95
101

Você também pode executar pesquisas sem distinção entre maiúsculas e minúsculas usando a pesquisa / correspondência sem o sinalizador IGNORECASE (testado no Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'
aem999
fonte
2
A documentação não menciona o recurso que está sendo adicionado em nenhuma versão específica (em vez de, digamos, o (?(condition)yes|no)que diz ter sido adicionado na 2.4), então espero que esteja sempre disponível desde a primeira versão do remódulo, que eu acho que foi adicionada em 1.5. Basicamente desde o início dos tempos para todos os efeitos, quando se trata de Python. Ele está documentado sobre a meio da primeira seção desta página: docs.python.org/2/library/re.html#regular-expression-syntax
ArtOfWarfare
4
Aqui vamos nós - procurei na documentação a versão 1.5 e a encontrei documentada em cerca de 60% desta página: docs.python.org/release/1.5/lib/… Também verifiquei a documentação 1.4, que não mencionava esse recurso. Então eu acho que foi adicionado na 1.5, quando o regexmódulo foi preterido em favor do remódulo.
ArtOfWarfare
3
Esta é uma boa solução, pois não requer uma bandeira. No meu caso, estou armazenando cadeias de pesquisa em Redis e isso é realmente útil.
Privado
3
@ Privado: conceitualmente, ele define a bandeira re.I em todo o regex - não apenas no grupo de captura que precede. Esteja ciente de que re.match(r'''A ((?i)B) C''', "a b c").group(0)causa uma correspondência que não diferencia maiúsculas de minúsculas em tudo (A e C), não apenas em B! Se você quer apenas insensibilizar maiúsculas e minúsculas em um grupo de captura específico, este não é o dróide que você está procurando.
SMCI
1
@ Privado: sim totalmente. Meu ponto de vista é conceitualmente, é o mesmo que definir uma bandeira. Em todo o regex. Até os grupos que a precedem (!). Não há sintaxe para dizer "sem distinção entre maiúsculas e minúsculas apenas nos seguintes grupos de captura".
SMCI
53

O marcador que não diferencia maiúsculas de minúsculas, (?i)pode ser incorporado diretamente no padrão regex:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']
Raymond Hettinger
fonte
2
Melhor opção, faz com que o portátil regex em todas as plataformas e intenção é clara na declaração
Sina Madani
1
Essa '(?i)'abordagem também tem a vantagem de criar uma lista de regexp's, algumas que não diferenciam maiúsculas de minúsculas e outras não. (E, claro, você pode mapear re.compilesobre essa lista, se quiser.)
não-apenas-yeti
@SinaMadani Estou confusa. Como isso é mais portátil do que flags=re.IGNORECASE?
Romain Vincent
10

Você também pode definir distinção entre maiúsculas e minúsculas durante a compilação do padrão:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
panofish
fonte
5
Na pergunta, o OP usa isso e pergunta se há outra maneira de fazer isso.
Peter
6
Útil para os de rolagem rápida.
SteveK
6

Nas importações

import re

No processamento em tempo de execução:

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

Deve-se mencionar que não usar re.compileé um desperdício. Sempre que o método de correspondência acima for chamado, a expressão regular será compilada. Isso também é uma prática defeituosa em outras linguagens de programação. A seguir, é a melhor prática.

Na inicialização do aplicativo:

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

No processamento em tempo de execução:

if self.RE_TEST.match('TeSt'):
Douglas Daseeco
fonte
1
Obrigado! Ninguém nunca fala em compilar, mas é a opção mais inteligente!
StefanJCollier
2
O OP pede literalmente para uma solução que não usar 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
fonte
4

Para executar operações que não diferenciam maiúsculas de minúsculas, forneça re.IGNORECASE

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

e se quisermos substituir o texto correspondente ao 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
fonte
1

Se você gostaria de substituir, mas ainda mantendo o estilo de str anterior. É possível.

Por exemplo: realce a sequência "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)

teste asdasd TEST asd tEst asdasd

Dat Nguyen
fonte
0

Para Expressão regular sem distinção entre maiúsculas e minúsculas (Regex): Existem duas maneiras de adicionar seu código:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
  2. O marcador que não diferencia maiúsculas de minúsculas (?i)

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