我需要处理文本以创建字典{name:Quantity}
文本变体:
2 Cardname
3 Cardname Two
1 Cardname Three
Cardname
Cardname Two
Cardname Three
所以我写了一个基本代码:
card_list = card_area.splitlines()
card_dict = {}
for card in card_list:
qty_re = re.search('^\d{1,6}', card)
if qty_re:
qty = qty_re.group()
else:
qty = 1
name_re = re.search('[A-Za-z ]+$', card)
if name_re:
name = name_re.group()
else:
name = None
if name:
card_dict[name] = qty
第一个问题:我可以使用 groupdict method如果字符串的某些元素不存在(无数量或空字符串)。
第二:我也想考虑这样的格式:
2 x Cardname
3x Cardname Two
1 xCardname Three
1xCardname Four
最好的方法是什么?
最佳答案
解决方案。注意事项。
from collections import defaultdict
import re
# card_list = card_area.splitlines()
card_list = [
"2 Cardname", "3 Cardname Two", "1 Cardname Three",
"Cardname", "Cardname Two", "Cardname Three",
"1x Cardname", "4X Cardname Two", "2 X Cardname Three",
]
card_dict = defaultdict(int)
pat = re.compile(r'(\d*)\s*(?:[xX]\s+)?(\S.*)')
for card in card_list:
m = re.search(pat, card)
if not m:
continue
if m.group(1):
qty = int(m.group(1))
else:
qty = 1
name = m.group(2)
card_dict[name] += qty
if not card_dict:
print("empty card_dict!")
else:
for name in sorted(card_dict):
print("%20s|%4d" % (name, card_dict[name]))
注释:
为了提高速度,我建议预编译正则表达式模式。
处理此问题的最佳方法是使用单个正则表达式模式来获取计数和卡片。我添加了一个可选模式,可以使用可选的“x”识别卡片格式;使用字符类,我使其匹配大写或小写“x”。数字和“x”之间的空格是可选的,但“x”和卡名称之间必须有空格,否则“x”将被视为卡名称的一部分。
里>如果您不熟悉正则表达式,请按以下方式阅读此表达式:形成一个匹配零个或多个数字的匹配组。接下来是零个或多个空白字符。其后是另一个组,但该组标记为
(?:
而不仅仅是(
所以它是一个组,但不会在输出中形成匹配组;该组是匹配“x”或“X”后跟一个或多个空白字符的字符类。形成另一个匹配组,该匹配组以一个非空白字符开头,后跟零个或多个任意字符。我相信您想对所有同名的牌求和?最好的方法是使用
defaultdict()
正如我在这里展示的。如果没有合法的卡牌名称以“x”或“X”开头,您可以更改模式以不保留“x”,即使它与卡牌名称之间没有空格。为此,请更改模式以匹配以下的“x”:
(?:[xX]\s+)?
对此:(?:[xX]\s*)?
(请注意,在+
之后,单个*
更改为单个\s
,因此现在将接受零个空白字符。)
关于python - 使用groupdict将字符串解析为dict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10182628/