Python用delimeter将行转换为列,数据包含***需要根据

2024-04-20 14:15:12 发布

您现在位置:Python中文网/ 问答频道 /正文

**START
IB    1107518415
BI    Paperback
BC    JHBC
CO    United Kingdom
ED    Alvarez, R. Michael
**
IB   0415836662
BI   Paperback
AU   Pituch, Keenan A.
AU    Stevens, James P.
BC   JHBC
CO   United Kingdom
EI    6 Rev ed

请查找以上样本数据,我需要在IB->第一排是1107518415“,第二排是0415836662”,依此类推,请帮帮我


Tags: startunitedkingdomauibbcbico
2条回答

您可以使用regex(txt具有示例字符串):

>>> import re
>>> re.findall(r'^\*\*.*\s+IB\s+(\d+)', txt, re.M)
['1107518415', '0415836662']

Explanation of regex


根据评论更新:

如果需要所有字段,比如在dict中,仍然可以使用正则表达式和循环:

fl=[]
for m in re.finditer(r'^\*\*.*\s+([\s\S]+?)(?=^\*\*|\Z)', txt, re.M):
    di={}
    for s in m.group(1).splitlines():
        k,v=re.split(r'\s+', s, maxsplit=1)
        di[k]=v
    fl.append(di)
>>> fl
[{'ED': 'Alvarez, R. Michael', 'IB': '1107518415', 'CO': 'United Kingdom', 'BI': 'Paperback', 'BC': 'JHBC'}, {'EI': '6 Rev ed', 'BC': 'JHBC', 'BI': 'Paperback', 'AU': 'Stevens, James P.', 'CO': 'United Kingdom', 'IB': '0415836662'}]

或者,可以使用单个压缩:

>>> [{k:v for k, v in [re.split(r'\s+', s, maxsplit=1) for s in sl]} 
... for sl in 
... [e.splitlines() for e in re.findall(r'^\*\*.*\s+([\s\S]+?)(?=^\*\*|\Z)', txt, re.M)]]
[{'ED': 'Alvarez, R. Michael', 'IB': '1107518415', 'CO': 'United Kingdom', 'BI': 'Paperback', 'BC': 'JHBC'}, {'EI': '6 Rev ed', 'BC': 'JHBC', 'BI': 'Paperback', 'AU': 'Stevens, James P.', 'CO': 'United Kingdom', 'IB': '0415836662'}]

不完全清楚你想要什么。如果您想要一个包含所有IB行中的值的列表,请尝试

res = [line.split(maxsplit=1)[1] for line in data.splitlines() if line.startswith("IB")]
# ['1107518415', '0415836662']

data是一个包含数据的多行字符串(当然,也可以是一个文件。)如果要将行拆分为由这些**分隔的组,可以使用for循环,将其附加到嵌套列表

res = []
for line in data.splitlines():
    if line.startswith("**"):
        res.append([])
    else:
        res[-1].append(line.split(maxsplit=1)[1])
# [['1107518415', 'Paperback', 'JHBC', 'United Kingdom', 'Alvarez, R. Michael'],
#  ['0415836662', 'Paperback', 'Pituch, Keenan A.', 'Stevens, James P.', 'JHBC', 'United Kingdom', '6 Rev ed']]

或者使用itertools.groupby作为“一行”,结果相同:

res = [[line.split(maxsplit=1)[1] for line in group] 
       for key, group in itertools.groupby(data.splitlines(), 
                                           key=lambda line: line.startswith("**")) 
       if key == False]

相关问题 更多 >