开发者

Whether to simplify two stage regular expression?

I'm newbie in Python, but this question is not a homework (actually this code helps to generate RSS on my Subversion server).

I have an array of strings in the info_lines variable. And I want to replace each occurrence of the bug ID. My current code looks like the following:

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:] )

It should replace the following te开发者_开发技巧xt:

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

with this one:

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

Notice that 1024 shouldn't be replaced with the link.

My current code do the job, but I interested whether it could be simplified, optimized, etc. May be it could be replaced with only one replacement regular expression? Or it could be replaced with one magic Python function from known libraries?


No, there's not much of a better way to do it. The replacement code messes up the case where there are bug numbers and other numbers on the same line, but even so, you're not getting away from two res because you want support for a comma-separated bug list.

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

Output:

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.

If you required every bug number to be prefixed with "FIX:" or "BUG:", then things get much simpler:

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

Output:

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.


I would say that it's fine as-is, although I personally would prefer different syntax for bug numbers. I would differentiate them from bare numbers by either having "bug 144", "issue 196" or just "#153". That means they can then be embedded in a longer message, to provide clearer context. This is especially helpful in cases like "Preliminary work for bug 355" or "Finishing clearup from #1293".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜