是否简化两阶段正则表达式?

时间:2009-12-15 12:34:16

标签: python regex

我是Python的新手,但这个问题不是作业(实际上这段代码有助于在我的Subversion服务器上生成RSS)。

我在info_lines变量中有一个字符串数组。我想替换每次出现的错误ID。我当前的代码如下所示:

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函数替换它?

2 个答案:

答案 0 :(得分: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:”或“BUG:”作为前缀,那么事情会变得更简单:

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.

答案 1 :(得分:0)

我会说这很好,虽然我个人更喜欢错误编号的不同语法。我会通过“bug 144”,“issue 196”或“#153”将它们与裸号区分开来。这意味着它们可以嵌入更长的消息中,以提供更清晰的上下文。这在“bug 355的初步工作”或“从#1293完成清理”等情况下特别有用。