2010-08-06 18 views
13

Bir işlev içinde bir regex derlerseniz ve bu işlev birden çok kez çağrılırsa, Python her seferinde normal ifadeyi yeniden derler veya Python derlenmiş düzenli ifadeyi önbelleğe alır (normal ifadeler varsayılarak) değişme ÖrneğinBirden çok kez çağrılan bir işlev içinde bir normal ifadeyi derleme

:

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 

cevap

11

Re modülündeki koda bakarsanız, re.compile işlevi, diğer tüm işlevler gibi önbelleği kullanır. Yapmak, tekrar tekrar aynı regex derlemek çok çok ucuz (sözlük arama). Başka bir deyişle, en anlaşılır veya sürdürülebilir veya etkileyici olmasını kod yazmak ve regexes derleme yükü dert etmeyin.

+0

Sen [re.py işlev _compile] sağ görüyorsanız (https://github.com/python/cpython/blob/master/Lib/re.py#L278) – pevik

6

, yapabileceğiniz:

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

1 Benim sözüm, ben * Python'ın varsayılan argüman taşıma * kullanışlı göreceğimi düşünmemiştim. – katrielalex

2

Neden sadece re.compile dışında işlevleri koymayın (modül veya sınıf düzeyinde), ona açık bir isim verin ve sadece onu kullanın? Bu tür bir regex bir çeşit sabittir ve aynı şekilde tedavi edebilirsiniz.

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

def contains_text_of_interest(line): 
    return MATCH_FOO_BAR.match(line) 
+3

Bu defa yapıyorum budur, ancak bu daha uzağa kullanımından kaynaklanan isterim daha regex tanımlamak için beni zorlar. –

2

Dingo çözümü iyi bir tanesidir [değiştir: Ned Batchelder yaptığı açıklama da iyidir], ama burada düzgün olduğunu düşünüyorum başka bir: kullanım kapanışları! Bu size "büyük bir kelime" gibi geliyorsa, endişelenmeyin.

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 yalnızca bir kez denir ve bu nedenle regex sadece bir kez derlenmektedir: kavram basittir.'a atanan f işlevi, çevreleyen kapsamda olduğu için derlenmiş düzenli ifade (matcher) hakkında bilgi sahibi olur ve contains_text_of_interest'u başka bir yerde kullansanız bile bu konu hakkında her zaman bilgi sahibi olur (kapaklar: kapsamı bu kapsamı alan kod) .

mutlaka bu soruna değil en Pythonictir çözüm. Ama zaman doğru olduğu zaman, senin kolunu yukarı almak için iyi bir deyim :)

İlgili konular