Компиляция регулярного выражения внутри функции, которая вызывается несколько раз - PullRequest
14 голосов
/ 07 августа 2010

Если вы компилируете регулярное выражение внутри функции, и эта функция вызывается несколько раз, Python каждый раз перекомпилирует регулярное выражение или Python кэширует скомпилированное регулярное выражение (при условии, что регулярное выражение не изменяется)?

Например:

def contains_text_of_interest(line):
    r = re.compile(r"foo\dbar\d")  
    return r.match(line)

def parse_file(fname):
    for line in open(fname):
        if contains_text_of_interest(line):
           # Do something interesting

Ответы [ 5 ]

12 голосов
/ 07 августа 2010

На самом деле, если вы посмотрите на код в модуле re, функция re.compile использует кэш точно так же, как и все остальные функции, поэтому компиляция одного и того же регулярного выражения снова и снова становится очень дешевой (поиск по словарю) , Другими словами, напишите код, который будет наиболее понятным, понятным или выразительным, и не беспокойтесь о накладных расходах на компиляцию регулярных выражений.

6 голосов
/ 07 августа 2010

Если вы хотите избежать дополнительных затрат на вызов re.compile () каждый раз, вы можете сделать:

def contains_text_of_interest(line, r = re.compile(r"foo\dbar\d")): 
    return r.match(line) 
2 голосов
/ 07 августа 2010

Хорошее решение Динго [править: объяснение Неда Батчелдера еще лучше], но вот еще одно, которое, на мой взгляд, изящно: используйте замыкания!Если это звучит как "большое слово" для вас, не волнуйтесь.Концепция проста:

def make_matching_function():
    matcher = re.compile(r"foo\dbar\d")
    def f(line):
        return matcher.match(line)
    return f
contains_text_of_interest = make_matching_function()

make_matching_function вызывается только один раз, и поэтому регулярное выражение компилируется только один раз.Функция f, назначенная contains_text_of_interest, знает о скомпилированном регулярном выражении matcher, потому что она находится в окружающей области видимости, и всегда будет знать об этом, даже если вы используете contains_text_of_interest где-то еще (это замыкания: codeэто берет на себя все вокруг).

Конечно, не самое питонское решение этой проблемы.Но это хорошая идиома, когда ты в рукаве, когда настало время:)

2 голосов
/ 07 августа 2010

Почему бы вам просто не поместить re.compile вне функций (на уровне модуля или класса), дать ему явное имя и просто использовать его? Такое регулярное выражение является своего рода константой, и вы можете обращаться с ним таким же образом.

MATCH_FOO_BAR = re.compile(r"foo\dbar\d")  

def contains_text_of_interest(line):
    return MATCH_FOO_BAR.match(line)
0 голосов
/ 07 августа 2010

Это делает "неправильно", вот более длинная тема по теме.

Я использую регулярные выражения Python с преступной неэффективностью

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