Регулярное выражение без учёта регистра без использования re.compile?
У меня возникла проблема с использованием регулярных выражений в Python. Я могу скомпилировать регулярное выражение так, чтобы оно игнорировало регистр, используя функцию re.compile
, как показано в следующем примере:
import re
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
. Я не нахожу в документации ничего, аналогичного суффиксу i
в Perl (например, m/test/i
). Есть ли у кого-то идеи или решения для этой задачи?
5 ответ(ов)
Вы также можете выполнять нечувствительные к регистру поиск с помощью функций search
и match
без использования флага IGNORECASE
(тестировано на Python 2.7.3):
re.search(r'(?i)test', 'TeSt').group() ## вернет 'TeSt'
re.match(r'(?i)test', 'TeSt').group() ## вернет 'TeSt'
Таким образом, регулярные выражения с модификатором (?i)
позволяют производить поиск без учета регистра.
Вы можете использовать безучётный модификатор (?i)
прямо в шаблоне регулярного выражения. Вот пример на Python с использованием модуля re
:
import re
s = 'This is one Test, another TEST, and another test.'
result = re.findall('(?i)test', s)
print(result) # Вывод: ['Test', 'TEST', 'test']
В данном примере re.findall
ищет все вхождения слова "test" независимо от регистра в строке s
, и результатом будет список, содержащий все найденные варианты слова.
Вы можете также задать регистронезависимость при компиляции шаблона следующим образом:
pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)
Это позволит вашему регулярному выражению игнорировать регистр символов, что упростит поиск совпадений, независимо от того, написан ли текст в верхнем или нижнем регистре.
Когда вы используете регулярные выражения в Python, важно учитывать, что компиляция регулярного выражения каждый раз при вызове метода match
может привести к излишним затратам по ресурсам. Ваш пример использования:
import re
RE_TEST = r'test'
if re.match(RE_TEST, 'TeSt', re.IGNORECASE):
не является оптимальным. Каждый раз, когда вы вызываете re.match
, регулярное выражение компилируется заново, что может негативно сказаться на производительности, особенно если этот код выполняется в цикле или часто вызывается.
Лучшей практикой будет предварительная компиляция регулярного выражения во время инициализации вашего приложения:
self.RE_TEST = re.compile('test', re.IGNORECASE)
А затем, при выполнении самого матчинга, вы можете использовать уже скомпилированное выражение:
if self.RE_TEST.match('TeSt'):
Таким образом, вы уменьшите накладные расходы на компиляцию и сделаете ваш код более эффективным.
Чтобы выполнить операции без учета регистра, используйте параметр 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'
В этом примере функция matchcase
определяет, как именно будет выглядеть заменяемое слово в зависимости от регистра найденного текста.
Фильтрация DataFrame pandas по критериям подстроки
Стоит ли использовать re.compile в Python?
Как сопоставить любой символ на нескольких строках в регулярном выражении?
Как выполнить регистронезависимое сравнение строк?
Разделить строку по запятым, игнорируя запятые внутри двойных кавычек?