tags:

views:

102

answers:

2

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"&gt;\1&lt;/a&gt;', info_lines[ln] )
formatted_lines = "<br/>".join( info_lines[3:] )

It should replace the following text:

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"&gt;10&lt;/a&gt;, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=24"&gt;24&lt;/a&gt;, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=3355"&gt;3355&lt;/a&gt;
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?

A: 

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".

Dave
The syntax is there: "BUG:" or "FIX:" followed by a comma-separated list of numbers. The bug is in the *replacement* code, however, since it will link all the numbers, prefixed or not.
Mike D.
Ah, my mistake -- I completely missed those line prefixes.
Dave
+2  A: 

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"&gt;\1&lt;/a&gt;'
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"&gt;10&lt;/a&gt;, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=24"&gt;24&lt;/a&gt;, <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=3355"&gt;3355&lt;/a&gt;
FIX: error 1024 was fixed
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=15"&gt;15&lt;/a&gt; (dupe of BUG:<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=25"&gt;25&lt;/a&gt;) 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"&gt;\2&lt;/a&gt;'
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"&gt;10&lt;/a&gt;, 24, 3355
FIX: error 1024 was fixed
FIX: <a href="http://bugzilla.mycompany.com/show_bug.cgi?id=15"&gt;15&lt;/a&gt; (dupe of BUG:<a href="http://bugzilla.mycompany.com/show_bug.cgi?id=25"&gt;25&lt;/a&gt;) fixed crash on x = 250.
Mike D.