【问题标题】:regex to split %ages and values in python正则表达式在 python 中拆分 %ages 和值
【发布时间】:2014-10-27 00:21:49
【问题描述】:

您好,我是 python 和正则表达式的新手。 我有一个大型 CSV 文件,其中有一个类似 %age composition 的字段,其中包含以下值:

'34% passed 23% failed 46% deferred'

你将如何拆分这个字符串,以便得到一个字典对象:

{'passed': 34, 'failed': 23, 'deferred': 46} 每行?

我试过这个:

for line in csv_lines:
    for match in re.findall('[\d\s%%]*\s', line)

但这只取了 %age 值

【问题讨论】:

  • 您可以查看此站点以帮助构建正则表达式:txt2re.com。否则,请向我们展示您的尝试,以便我们帮助您改进它们,而不仅仅是请人为您做。

标签: python regex


【解决方案1】:

如果你仍然想使用正则表达式,你可以使用这个:

(\w+)%\s(\w+)

这将匹配一个或多个字母数字字符(替代:[0-9a-zA-Z_]+),后跟 % 符号、空格字符和一个或多个字母数字字符。括号帮助 capturing 适当的字符集。

演示:

>>> import re
>>> s = '34% passed 23% failed 46% deferred'
>>> pattern = re.compile(r'(\w+)%\s(\w+)')
>>> {value: key for key, value in pattern.findall(s)}
{'failed': '23', 'passed': '34', 'deferred': '46'}

【讨论】:

  • 你在我之前得到了它 :) 并且更清洁
  • @Ashwin 也一样,falsetru 让我提供了基于正则表达式的方法 :)
【解决方案2】:

你不需要使用正则表达式:

>>> s = '34% passed 23% failed 46% deferred'
>>> groups = zip(*[iter(s.split())]*2)
>>> groups
[('34%', 'passed'), ('23%', 'failed'), ('46%', 'deferred')]
>>> {result: int(percent.rstrip('%')) for percent, result in groups}
{'failed': 23, 'passed': 34, 'deferred': 46}

zip(*[iter(..)]*2) 来自grouper - itertools recipes(另见How does zip(*[iter(s)]*n) work in Python?):

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

【讨论】:

  • 可能值得链接到 explanationzip-iter 魔法。
  • @DSM,感谢您的评论。我相应地更新了答案。
【解决方案3】:

试试这个:

[编辑:添加了对根据 OP 请求检查的单词的列表支持。还清理了alecx 在这里使用的字典构建代码:https://stackoverflow.com/a/25628562/3646530]

import re

data = """34% passed 23% failed 46% deferred 34% checked"""
checkList = ['passed', 'failed', 'deferred', 'checked']
result = {k:v for (v, k) in re.findall('(\d{1,3})% (' + '|'.join(checkList) + ')', data)}
print(result) # Python 3
#print result # Python 2.7

这里的正则表达式是 \d{1,3} - 捕获百分比 int 并通过|失败|延迟来获取类型。我使用列表推导生成键和值元组的列表,然后将其转换为字典

为了构建字符串'passed|failed| ..' 我使用字符串的 .join 函数来连接 checkList 中的单词,并以竖线字符作为分隔符。

【讨论】:

  • \w+ 可能会更好,以防这些只是可能选项的示例。抓住紧随其后的词会比可能的列表更好。
  • 所以,像result = dict([(k,v) for (v, k) in re.findall('(\d{1,3})%\w+', data)]) 这样在 %age 之后抓取单词?
  • 您如何将passed|failed|deferred 链接到具有其他要检查的值的列表?
  • @aqoon 编辑了我的答案以支持这一点。 \w+ 也将匹配之后的所有单词。但是为了抓住它,你必须将它分组。因此使用 (\w+) 将对其进行分组并使其可访问。将正则表达式放入这样的工具中:debuggex.com 以可视化您的组并测试您的正则表达式
猜你喜欢
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 2022-01-25
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
相关资源
最近更新 更多