Регулярное выражение без учета регистра без re.compile?

В Python я могу скомпилировать регулярное выражение без учета регистра, используя 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>

Есть ли способ сделать то же самое, но без использования re.compile. Я не могу найти в документации ничего похожего на суффикс Perl i (например, m/test/i).


person Mat    schedule 01.02.2009    source источник
comment
Вы можете найти отличное введение в регулярные эксперименты по адресу: python-course.eu/re.php   -  person 2Obe    schedule 22.07.2017


Ответы (8)


Передайте re.IGNORECASE параметру flags в search, _ 4_ или _ 5_:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)
person Michael Haren    schedule 01.02.2009
comment
re.match('test', 'TeSt', re.IGNORECASE) может привести к TypeError, если любой из атрибутов равен None. Использование try & except для поиска совпадений TypeError по first_string == second_string. Образец кода 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 Демо-код - person Abhijeet; 27.01.2017
comment
@Abhijeet Вы действительно не должны использовать try /, кроме этого случая. Просто проверьте, не является ли какая-либо из строк None первой. - person erb; 21.10.2019
comment
Важно использовать именованный аргумент flags для re.sub, иначе он передает re.IGNORECASE аргументу count (s. Также stackoverflow.com/questions/42581/) - person L3n95; 15.01.2020

Вы также можете выполнять поиск без учета регистра, используя поиск / сопоставление без флага IGNORECASE (проверено в Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'
person aem999    schedule 04.05.2012
comment
В документации не упоминается функция, добавляемая в какую-либо конкретную версию (в отличие от, скажем, (?(condition)yes|no), которая, как говорится, была добавлена ​​в 2.4), поэтому я ожидаю, что она всегда была доступна с первой версии модуля re, что, как мне кажется, был добавлен в 1.5. По сути, с незапамятных времен для всех намерений и целей, когда дело доходит до Python. Он задокументирован примерно в середине первого раздела этой страницы: docs .python.org / 2 / library / re.html # синтаксис регулярного выражения - person ArtOfWarfare; 05.05.2015
comment
Вот и все - я просмотрел документацию по 1.5 и обнаружил, что она задокументирована примерно на 60% пути вниз по этой странице: docs.python.org/release/1.5/lib/ Я также проверил документацию 1.4, в которой эта функция не упоминается. Думаю, он был добавлен в 1.5, когда модуль regex устарел в пользу модуля re. - person ArtOfWarfare; 05.05.2015
comment
Это хорошее решение, так как не требует флага. В моем случае я храню строки поиска в Redis, и это действительно полезно. - person Private; 08.09.2016
comment
Например, [st for st in filter(lambda x: not search(r'(?i)Mac', x), ['macintosh','tomato','MacMahon', 'and', 'maCaroni', 'pasta'])] отфильтрует все совпадения [Mm] [Aa] [Cc] и оставит нам только ['tomato', 'and', 'pasta'] - person rloth; 07.10.2016
comment
@Private: концептуально он устанавливает флаг re.I для всего регулярного выражения, а не только для группы захвата, которой он предшествует. Имейте в виду, что re.match(r'''A ((?i)B) C''', "a b c").group(0) вызывает сопоставление без учета регистра для всего (A и C), а не только для B! Если вам нужно только сопоставление без учета регистра для определенной группы захвата, это не тот дроид, который вам нужен. - person smci; 05.12.2017
comment
@Private: да, полностью. Я хочу сказать, что концептуально это то же самое, что и установка флага. На всем регулярном выражении. Даже группы, которые ему предшествуют (!). Не существует синтаксиса, позволяющего указать регистронезависимость только для следующих групп захвата. - person smci; 05.12.2017
comment
@smci Я думаю, это следует отредактировать в самом ответе. - person Private; 06.12.2017

Маркер без учета регистра (?i) может быть включен непосредственно в шаблон регулярного выражения:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']
person Raymond Hettinger    schedule 23.02.2017
comment
Лучший вариант, делает регулярное выражение переносимым между платформами, и намерение ясно при объявлении - person Sina Madani; 23.11.2017
comment
Этот '(?i)' подход также имеет то преимущество, что вы можете создать список регулярных выражений, некоторые из которых нечувствительны к регистру, а некоторые нет. (И, конечно, вы можете нанести re.compile на этот список, если хотите.) - person not-just-yeti; 02.09.2019
comment
@SinaMadani Я в замешательстве. Насколько это портативнее, чем flags=re.IGNORECASE? - person Romain Vincent; 19.03.2020
comment
@RomainVincent более портативен, так как вы можете просто скопировать и вставить сам шаблон и использовать его в другом месте. Я еще не уверен, нравится ли мне такой подход. - person Robo Robok; 09.09.2020
comment
@RoboRobok Ах да, я не думал об этом так. Спасибо за ваш ответ! - person Romain Vincent; 18.09.2020

Вы также можете определить регистр без учета регистра во время компиляции шаблона:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
person panofish    schedule 12.05.2014
comment
В вопросе OP использует это и спрашивает, есть ли другой способ сделать это. - person Peter Wood; 15.05.2015
comment
Полезно для тех, кто быстро прокручивает. - person Steve K; 23.03.2016

В импорте

import re

При обработке во время выполнения:

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

Следует отметить, что неиспользование re.compile расточительно. Каждый раз, когда вызывается указанный выше метод сопоставления, регулярное выражение компилируется. Это также ошибочная практика в других языках программирования. Ниже представлена ​​лучшая практика.

При инициализации приложения:

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

При обработке во время выполнения:

if self.RE_TEST.match('TeSt'):
person Douglas Daseeco    schedule 01.06.2017
comment
Спасибо! Никто никогда не говорит о компиляции, но это самый разумный вариант! - person Stefan Collier; 18.08.2018
comment
OP буквально требует решения, которое не использует _1 _.... - person wpercy; 06.02.2019

Чтобы выполнять операции без учета регистра, укажите re.IGNORECASE

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

и если мы хотим заменить текст, соответствующий регистру ...

>>> 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'
person Srivastava    schedule 21.06.2019

Если вы хотите заменить, но при этом сохраните стиль предыдущей стр. Возможно.

Например: выделите строку «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)

тест asdasd ТЕСТ asd tEst asdasd

person Dat    schedule 04.11.2019

Для регулярного выражения без учета регистра (Regex): есть два способа добавления в ваш код:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
    
  2. Маркер без учета регистра (?i)

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