Python:从括号中提取信息

时间:2014-07-06 20:19:04

标签: python regex string split

我目前有10个人,A通过K。他们的每个分数都是在玩家姓名之后插入的,例如A(12)F(99)

例如,我目前的足球队名单就是这样:

A(14)B(12)C(9)D(16)E(14)F(23)G(25)H(12)I(3)JK(14).

在此示例中,J没有积分。 (正如你所知,我没有多少练习。如果你能看到这个,杰夫,练习更多。那就是你。:D)

将此列表中的信息提取到新列表

scores=['A', 14, 'B', 12, 'C', 9, ...]

现在,打印从最高到最低的分数,并在第一个之后打印(Gold),在第二个之后打印(Silver),然后打印第三个之后的(Bronze),这样。可以按任何顺序打印相同的分数。

G: 25 (Gold)
F: 23 (Silver)
D: 16 (Bronze)
A: 14 
E: 14
etc.

谢谢,如果这篇文章没有帮助,请告诉我如何改进。

我目前正在尝试

>>> re.split("[()]", 'A(14)B(12)C(9)D(16)E(14)F(23)G(25)H(12)I(3)JK(14)')

哪个给了我

['A', '14', 'B', '12', 'C', '9', 'D', '16', 'E', '14', 'F', '23', 'G', '25', 'H', '12', 'I', '3', 'JK', '14', '']

我喜欢这个,但JK在一起。请帮忙。

2 个答案:

答案 0 :(得分:1)

我会使用不同的正则表达式,一个为您提供单独的(name, count)对的正则表达式:

import re

re.findall(r'([A-Z])(?:\((\d+)\))?', inputtext)

这会查找A-Z范围内的字母(留出扩展空间),可选(?:..)?),后跟parethenses中的数字(\( \)是字面括号,\d+是1位或更多位数。

re.findall()生成字符串中所有匹配项的列表,每个匹配项都是模式中两个组的元组(每个(...)封闭模式),所以字母后跟分数(或一个空字符串,用于J):

>>> import re
>>> inputtext = 'A(14)B(12)C(9)D(16)E(14)F(23)G(25)H(12)I(3)JK(14).'
>>> re.findall(r'([A-Z])(?:\((\d+)\))?', inputtext)
[('A', '14'), ('B', '12'), ('C', '9'), ('D', '16'), ('E', '14'), ('F', '23'), ('G', '25'), ('H', '12'), ('I', '3'), ('J', ''), ('K', '14')]

这些对比单个平面列表中任意混合的字母和数字更实用;你的号码现在与你的字母intead配对。

然后可以将每对用于输入collections.Counter() object,这可以方便您的排序:

from collections import Counter

points = Counter({name: int(count or 0) 
                  for name, count in re.findall(r'([A-Z])(?:\((\d+)\))?', inputtext)})

接下来,给出排名的映射:

ranks = {0: '(Gold)', 1: '(Silver)', 2: '(Bronze)'}

最后循环Counter.most_common()以按降序排序,并与enumerate()一起提供排名:

for i, (name, score) in enumerate(points.most_common()):
    print '{}: {} {}'.format(name, score, ranks.get(i, ''))

演示:

>>> import re
>>> from collections import Counter
>>> inputtext = 'A(14)B(12)C(9)D(16)E(14)F(23)G(25)H(12)I(3)JK(14).'
>>> re.findall(r'([A-Z])(?:\((\d+)\))?', inputtext)
[('A', '14'), ('B', '12'), ('C', '9'), ('D', '16'), ('E', '14'), ('F', '23'), ('G', '25'), ('H', '12'), ('I', '3'), ('J', ''), ('K', '14')]
>>> points = Counter({name: int(count or 0) 
...                   for name, count in re.findall(r'([A-Z])(?:\((\d+)\))?', inputtext)})
>>> points
Counter({'G': 25, 'F': 23, 'D': 16, 'A': 14, 'E': 14, 'K': 14, 'B': 12, 'H': 12, 'C': 9, 'I': 3, 'J': 0})
>>> ranks = {0: '(Gold)', 1: '(Silver)', 2: '(Bronze)'}
>>> for i, (name, score) in enumerate(points.most_common()):
...     print '{}: {} {}'.format(name, score, ranks.get(i, ''))
... 
G: 25 (Gold)
F: 23 (Silver)
D: 16 (Bronze)
A: 14 
E: 14 
K: 14 
B: 12 
H: 12 
C: 9 
I: 3 
J: 0 

答案 1 :(得分:0)

只需将JK()替换为J(0)K(),就像这样。它使用积极向前看。请参阅here

inputtext = 'A(14)B(12)C(9)D(16)E(14)F(23)G(25)H(12)I(3)JK(14).'
inputtext = re.sub(r"([A-Z])(?=[^(])", r"\1(0)", inputtext)

您也可以像这样删除J

inputtext = re.sub(r"([A-Z])(?=[^(])", r"", inputtext)

行。然后你可以随心所欲。