从SVN日志过滤<msg>仅选取票号</msg>

时间:2013-03-05 10:33:23

标签: python perl parsing svn xml-parsing

我正在使用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>

中未包含故障单####的修订日志

1 个答案:

答案 0 :(得分:1)

这是一个简单的解决方案:在单词Ticket:

之后查找第一个数字
if ($line =~ /Ticket\D+(\d+)/)
{
    $ticket_number = $1;
}

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

这是对Python版本的抨击(Caveat,我不是Python程序员):

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

if matchObj:
   print matchObj.group(1)

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

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

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

相关问题