1

我正在使用 python 将 SVN 的 XML 日志转换为 CSV ......

#!/usr/bin/env python

import csv
import subprocess
import sys
import xml.etree.cElementTree as etree

log_text = subprocess.Popen(['svn', 'log', '--xml'] + sys.argv[1:],
                            stdout=subprocess.PIPE).communicate()[0]
log_xml = etree.XML(log_text)

csv_writer = csv.writer(sys.stdout)

for child in log_xml.getchildren():
        csv_writer.writerow([
                child.attrib['revision'],
                child.findtext('date'), 
                child.findtext('author').encode('utf-8'),
                child.findtext('msg').encode('utf-8'),
        ])

例如,它将给出输出...

2022,2013-01-02T06:11:40.500850Z,dave.d@email.com,"Ticket 16057735 - Blah "
2023,2013-01-02T06:43:22.247709Z,john.c@email.com,Ticket:16060718 Blah Blah
2027,2013-01-02T07:43:00.326583Z,dave.d@email.com,Ticket 16060936 - Blah Blah

但我想<msg>在创建 .csv 输出时过滤/解析以仅获取票号。

使用 perl 之类的任何替代方法都不是问题。

更新:以任何方式跳过评论中没有票证####的修订日志(<msg>

4

1 回答 1

1

这是一个简单的解决方案:查找 Ticket 后面的第一个数字:

if ($line =~ /Ticket\D+(\d+)/)
{
    $ticket_number = $1;
}

使用 Perl 语法,但在 Python 中也应该很容易。

这是一个 Python 版本的尝试(注意,我不是 Python 程序员):

matchObj = re.match( r'Ticket\D+(\d+)', child.findtext('msg').encode('utf-8'))

if matchObj:
   print matchObj.group(1)

正则表达式Ticket\D+(\d+)匹配单词 ticket,然后是一个或多个非数字字符 ( \D+),然后是一个或多个数字 ( \d+)。括号捕获第一个匹配组中模式的封闭部分。

如果您希望匹配更具体,您可以使用(\d{8})确保票号有八位数字。

更新:这两种解决方案都使用if语句来指示模式匹配。您可以通过跳过不匹配的行来跳过没有票号的行。

于 2013-03-05T10:47:09.247 回答