我正在使用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>
)
答案 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
语句来指示模式匹配。您可以通过跳过不匹配的行来跳过没有票号的行。