Регулярные выражения в Python: работа с регистронезависимыми выражениями без использования re.compile
Регулярные выражения — мощный инструмент для работы со строками в Python. Они позволяют осуществлять сложные поисковые и заменяющие операции с текстом.
Регулярные выражения — мощный инструмент для работы со строками в Python. Они позволяют осуществлять сложные поисковые и заменяющие операции с текстом. Однако, иногда возникают ситуации, когда необходимо провести поиск без учета регистра символов, но при этом не использовать функцию re.compile .
Предположим, есть следующий код:
import re s = 'TeSt' casesensitive = re.compile('test') print(casesensitive.match(s))
В данном случае, функция match не найдет совпадение, так как она учитывает регистр символов. Для решения этой проблемы можно использовать функцию re.compile с параметром re.IGNORECASE , который позволяет игнорировать регистр символов.
import re s = 'TeSt' ignorecase = re.compile('test', re.IGNORECASE) print(ignorecase.match(s))
Теперь функция match находит совпадение, так как регистр символов игнорируется. Однако, что делать, если использование re.compile не подходит или неудобно по какой-то причине?
В Python есть возможность использовать такую же функциональность без re.compile с помощью функций re.search и re.match .
import re s = 'TeSt' print(re.match('test', s, re.IGNORECASE)) print(re.search('test', s, re.IGNORECASE))
Как видно, результаты работы функций re.match и re.search аналогичны результату работы функции re.compile с параметром re.IGNORECASE .
Таким образом, в Python есть возможность выполнить регистронезависимый поиск без использования re.compile , что может быть удобно в некоторых случаях.
Нечувствительное к регистру регулярное выражение без re.compile?
Есть ли способ сделать то же самое, но без использования re.compile . Я не могу найти ничего подобного Perl i суффикса (например, m/test/i ) в документации.
7 ответов
Передайте re.IGNORECASE параметру flags search , match или sub :
re.search('test', 'TeSt', re.IGNORECASE) re.match('test', 'TeSt', re.IGNORECASE) re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)
re.match(‘test’, ‘TeSt’, re.IGNORECASE) может привести к TypeError когда любой из атрибутов re.match(‘test’, ‘TeSt’, re.IGNORECASE) 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 Демонстрационный код
Вы также можете выполнять поиск без учета регистра, используя поиск/совпадение без флага IGNORECASE (тестируется в Python 2.7.3):
re.search(r'(?i)test', 'TeSt').group() ## returns 'TeSt' re.match(r'(?i)test', 'TeSt').group() ## returns 'TeSt'
В документации не упоминается функция, добавляемая в какой-либо конкретной версии (в отличие, скажем, (?(condition)yes|no) которая, по ее словам, была добавлена в 2.4), поэтому я ожидаю, что она всегда была доступна с первой версии re модуля, который, я думаю, был добавлен в 1.5. В основном с начала времен для всех намерений и целей, когда дело доходит до Python. Это описано примерно на полпути в первом разделе этой страницы: docs.python.org/2/library/re.html#regular-expression-syntax
Здесь мы идем — я просмотрел документацию для 1.5 и нашел, что она документирована примерно на 60% пути вниз по этой странице: docs.python.org/release/1.5/lib/… Я также проверил документацию 1.4, в которой не упоминалось эта особенность. Так что я думаю, что он был добавлен в 1.5, когда модуль regex устарел в пользу модуля re .
Это хорошее решение, так как оно не требует флага. В моем случае я храню строки поиска в Redis, и это действительно полезно.
Например, [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’]
@Private: концептуально он устанавливает флаг re.I для всего регулярного выражения, а не только для группы захвата, которой он предшествует. Помните, что re.match(r»’A ((?i)B) C»’, «ab c»).group(0) вызывает регистронезависимое сопоставление для всего (A и C), а не только для B! Если вы хотите, чтобы совпадение без учета регистра в определенной группе захвата происходило, это не тот дроид, которого вы ищете.
@ Частный: да, полностью. Моя точка зрения концептуально это то же самое, что установить флаг. На все регулярные выражения. Даже группы, предшествующие этому (!). Нет синтаксиса, чтобы сказать «нечувствителен к регистру только для следующих групп захвата».