2009-12-15 2 views
2

Я новичок в Python, но этот вопрос не является домашней работой (на самом деле этот код помогает генерировать RSS на моем сервере Subversion).Следует ли упростить двухэтапное регулярное выражение?

У меня есть массив строк в переменной info_lines. И я хочу заменить каждое появление идентификатора ошибки. Мой текущий код выглядит следующим образом:

for ln in range(3, len(info_lines)): # skip two strings since there are author&date info 
    if re.search(r'(?:BUG|FIX):(?:[ ,]*(\d+))+', info_lines[ln]): 
    info_lines[ln] = re.sub(r'(\d+)+', r'<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=\1">\1</a>', info_lines[ln]) 
formatted_lines = "<br/>".join(info_lines[3:]) 

Он должен заменить следующий текст:

STABLE 
FIX: some bug fixed 
FIX: 10, 24, 3355 
FIX: error 1024 was fixed 

с этим один:

STABLE 
FIX: some bug fixed 
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=10">10</a>, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=24">24</a>, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=3355">3355</a> 
FIX: error 1024 was fixed 

Обратите внимание, что 1024 не должен быть заменен ссылка.

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

+0

Является ли модификация сайта info_lines на месте, необходимой позже в программе? –

+0

№ 'info_lines' не будет использоваться позднее. –

ответ

2

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

import re 

info_lines = [ 
    "Me", 
    "now", 
    "STABLE", 
    "FIX: some bug fixed", 
    "FIX: 10, 24, 3355", 
    "FIX: error 1024 was fixed", 
    "FIX: 15 (dupe of BUG:25) fixed crash on x = 250." 
] 
linkText = r'<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=\1">\1</a>' 
bugSearch = re.compile(r'(?:BUG|FIX):(?:[ ,]*(\d+))+') 
bugMatch = re.compile(r'(\d+)') 

for k, ln in enumerate(info_lines[3:]): 
    while True: 
     m = bugSearch.search(ln) 
     if m: 
      ln = ln[:m.start()] + bugMatch.sub(linkText, m.group()) + ln[m.end():] 
     else: 
      break 
    info_lines[k+3] = ln 

for ln in info_lines: 
    print ln 

Выход:

Me 
now 
STABLE 
FIX: some bug fixed 
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=10">10</a>, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=24">24</a>, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=3355">3355</a> 
FIX: error 1024 was fixed 
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=15">15</a> (dupe of BUG:<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=25">25</a>) fixed crash on x = 250. 

Если вам требуется каждый номер ошибки, чтобы быть с префиксом "FIX:" или "Ошибка:", то все становится гораздо проще:

linkText = r'\1<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=\2">\2</a>' 
bugSearch = re.compile(r'((?:BUG|FIX):(?:)?)(\d+)') 

info_lines[3:] = [bugSearch.sub(linkText, ln) for ln in info_lines[3:]] 

for ln in info_lines: 
    print ln 

Выход:

Me 
now 
STABLE 
FIX: some bug fixed 
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=10">10</a>, 24, 3355 
FIX: error 1024 was fixed 
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=15">15</a> (dupe of BUG:<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=25">25</a>) fixed crash on x = 250. 
0

Я бы сказал, что это нормально, хотя я лично предпочел бы использовать другой синтаксис для номеров ошибок. Я бы выделил их из голых чисел, либо имея «ошибку 144», «выпуск 196», либо просто «# 153». Это означает, что они могут быть встроены в более длинное сообщение, чтобы обеспечить более четкий контекст. Это особенно полезно в таких случаях, как «Предварительная работа по ошибке 355» или «Финишная очистка от # 1293».

+0

Синтаксис: «BUG:» или «FIX:», а затем список номеров, разделенный запятыми. Однако ошибка указана в коде * замены *, так как она свяжет все числа с префиксом или нет. –

+0

А, моя ошибка - я полностью пропустил эти префиксы. – DMI

Смежные вопросы