我正在用Python编写程序来解析Ledger / hledger日志文件。
我在提出一个正则表达式方面遇到了问题,我确信这很简单。我想解析一个表格的字符串:
expenses:food:food and wine 20.99
并捕获帐户部分(冒号之间,允许任何空格),无论子帐户数量多少,以及组中的总数。子帐户名的最后一个字符与价格数字之间可以有任意数量的空格。
expenses:food:wine:speciality 19.99
也是允许的(子帐户中没有空格)。
到目前为止,我已经(\S+):|(\S+ \S+):|(\S+ (?!\d))|(\d+.\d+)
,不允许任何数量的子帐户和可能的空格。我不认为我希望在那里有OR
个运算符,因为这将与其他正则表达.join()
连接作为解析函数的一部分。
非常感谢任何帮助。
感谢。
答案 0 :(得分:0)
您可以使用以下内容:
((?:[^\s:]+)(?:\:[^\s:]+)*)\s*(\d+\.\d+)
现在我们可以使用:
s = 'expenses:food:wine:speciality 19.99'
rgx = re.compile(r'((?:[^\s:]+)(?:\:[^\s:]+)*)\s*(\d+\.\d+)')
mat = rgx.match(s)
if mat:
categories,price = mat.groups()
categories = categories.split(':')
现在categories
将是一个包含类别的列表,price
是一个包含价格的字符串。对于您的样本输入,这给出:
>>> categories
['expenses', 'food', 'wine', 'speciality']
>>> price
'19.99'
答案 1 :(得分:0)
你根本不需要正则表达式,原生str.split()
绰绰有余:
def split_ledger(line):
entries = line.split(":") # first split all the entries
last = entries.pop() # take the last entry
return entries + last.rsplit(" ", 1) # split on last space and return all together
print(split_ledger("expenses:food:food and wine 20.99"))
# ['expenses', 'food', 'food and wine ', '20.99']
print(split_ledger("expenses:food:wine:speciality 19.99"))
# ['expenses', 'food', 'wine', 'speciality ', '19.99']
或者,如果您不想要任何条目中的前导/尾随空格:
def split_ledger(line):
entries = [e.strip() for e in line.split(":")]
last = entries.pop()
return entries + [e.strip() for e in last.rsplit(" ", 1)]
print(split_ledger("expenses:food:food and wine 20.99"))
# ['expenses', 'food', 'food and wine', '20.99']
print(split_ledger("expenses:food:wine:speciality 19.99"))
# ['expenses', 'food', 'wine', 'speciality', '19.99']