Стоит ли использовать Python re.compile? - PullRequest
391 голосов
/ 17 января 2009

Есть ли преимущество в использовании компиляции для регулярных выражений в Python?

h = re.compile('hello')
h.match('hello world')

против

re.match('hello', 'hello world')

Ответы [ 24 ]

0 голосов
/ 06 ноября 2010

Я бы хотел мотивировать, что предварительная компиляция выгодна как концептуально, так и «буквально» (как в «грамотном программировании»). взгляните на этот фрагмент кода:

from re import compile as _Re

class TYPO:

  def text_has_foobar( self, text ):
    return self._text_has_foobar_re_search( text ) is not None
  _text_has_foobar_re_search = _Re( r"""(?i)foobar""" ).search

TYPO = TYPO()

в вашем приложении вы бы написали:

from TYPO import TYPO
print( TYPO.text_has_foobar( 'FOObar ) )

это примерно настолько просто с точки зрения функциональности, насколько это возможно. Поскольку этот пример очень короткий, я нашел способ получить _text_has_foobar_re_search в одной строке. недостаток этого кода в том, что он занимает мало памяти для любого времени жизни библиотечного объекта TYPO; Преимущество состоит в том, что при выполнении поиска в foobar вы получите два вызова функций и два поиска в словаре классов. сколько регулярных выражений кэшируется re, и издержки этого кэша здесь не имеют значения.

сравните это с более обычным стилем, приведенным ниже:

import re

class Typo:

  def text_has_foobar( self, text ):
    return re.compile( r"""(?i)foobar""" ).search( text ) is not None

В приложении:

typo = Typo()
print( typo.text_has_foobar( 'FOObar ) )

Я с готовностью признаю, что мой стиль весьма необычен для python, возможно, даже спорен. однако в примере, который более точно соответствует тому, как Python в основном используется, чтобы выполнить одно совпадение, мы должны создать экземпляр объекта, выполнить три поиска в словаре экземпляра и выполнить три вызова функций; Кроме того, мы можем столкнуться с проблемами re кэширования при использовании более 100 регулярных выражений. Кроме того, регулярное выражение скрывается внутри тела метода, что в большинстве случаев не очень хорошая идея.

следует сказать, что каждое подмножество мер --- целевые, псевдонимы по импорту; методы с псевдонимами, где это применимо; сокращение вызовов функций и поиска в словаре объектов --- может помочь уменьшить вычислительную и концептуальную сложность.

0 голосов
/ 17 января 2009

Насколько я понимаю, эти два примера фактически эквивалентны. Единственное отличие состоит в том, что в первом случае вы можете повторно использовать скомпилированное регулярное выражение в другом месте, не вызывая его повторную компиляцию.

Вот вам ссылка: http://diveintopython3.ep.io/refactoring.html

Вызов функции поиска скомпилированного шаблонного объекта со строкой «M» выполняет то же самое, что и вызов re.search с регулярным выражением и строкой «M». Только намного, намного быстрее. (На самом деле функция re.search просто компилирует регулярное выражение и вызывает для вас метод поиска результирующего объекта шаблона.)

0 голосов
/ 02 июня 2019

В качестве альтернативного ответа, поскольку я вижу, что это не упоминалось ранее, я продолжу и процитирую документы Python 3 :

Следует ли вам использовать эти функции уровня модуля или вы должны получить шаблон и вызывать его методы самостоятельно? Если вы обращаетесь к регулярному выражению в цикле, его предварительная компиляция сохранит несколько вызовов функций. Вне циклов нет особой разницы благодаря внутреннему кешу.

0 голосов
/ 17 января 2009

Регулярные выражения компилируются перед использованием при использовании второй версии. Если вы собираетесь выполнять его много раз, определенно лучше сначала скомпилировать его. Если вы не компилируете каждый раз, когда вы подходите для одного, это нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...