字符串拆分在新行,制表符和一些空格上

时间:2012-09-21 15:54:35

标签: python regex split

我正在尝试对一组有点不规则的数据执行字符串拆分,看起来像是:

\n\tName: John Smith
\n\t  Home: Anytown USA
\n\t    Phone: 555-555-555
\n\t  Other Home: Somewhere Else
\n\t Notes: Other data
\n\tName: Jane Smith
\n\t  Misc: Data with spaces

我想把它转换成一个元组/字典,然后我会在冒号:上拆分,但首先我需要摆脱所有额外的空格。我猜一个正则表达式是最好的方法,但我似乎无法得到一个有效的,下面是我的尝试。

data_string.split('\n\t *')

6 个答案:

答案 0 :(得分:77)

只需使用.strip(),它会在拆分时为您删除所有空格,包括标签和换行符。然后可以使用data_string.splitlines()

完成拆分
[s.strip() for s in data_string.splitlines()]

输出:

>>> [s.strip() for s in data_string.splitlines()]
['Name: John Smith', 'Home: Anytown USA', 'Phone: 555-555-555', 'Other Home: Somewhere Else', 'Notes: Other data', 'Name: Jane Smith', 'Misc: Data with spaces']

您甚至可以在:上内联分割:

>>> [s.strip().split(': ') for s in data_string.splitlines()]
[['Name', 'John Smith'], ['Home', 'Anytown USA'], ['Phone', '555-555-555'], ['Other Home', 'Somewhere Else'], ['Notes', 'Other data'], ['Name', 'Jane Smith'], ['Misc', 'Data with spaces']]

答案 1 :(得分:6)

>>> for line in s.splitlines():
...     line = line.strip()
...     if not line:continue
...     ary.append(line.split(":"))
...
>>> ary
[['Name', ' John Smith'], ['Home', ' Anytown USA'], ['Misc', ' Data with spaces'
]]
>>> dict(ary)
{'Home': ' Anytown USA', 'Misc': ' Data with spaces', 'Name': ' John Smith'}
>>>

答案 2 :(得分:5)

你可以用一块正则石头杀死两只鸟:

>>> r = """
... \n\tName: John Smith
... \n\t  Home: Anytown USA
... \n\t    Phone: 555-555-555
... \n\t  Other Home: Somewhere Else
... \n\t Notes: Other data
... \n\tName: Jane Smith
... \n\t  Misc: Data with spaces
... """
>>> import re
>>> print re.findall(r'(\S[^:]+):\s*(.*\S)', r)
[('Name', 'John Smith'), ('Home', 'Anytown USA'), ('Phone', '555-555-555'), ('Other Home', 'Somewhere Else'), ('Notes', 'Other data'), ('Name', 'Jane Smith'), ('Misc', 'Data with spaces')]
>>> 

答案 3 :(得分:3)

如果您str.split查看split

  

如果未指定sep或为None,则应用不同的拆分算法:连续空格的运行被视为单个分隔符,如果字符串具有前导或尾随,则结果将在开头或结尾处不包含空字符串空白。因此,将空字符串或仅由空格组成的字符串拆分为无分隔符将返回[]。

换句话说,如果您想弄清楚要传递给'\n\tName: Jane Smith'['Name:', 'Jane', 'Smith']s.split(None, 1) 的内容,请不要传递任何内容(或无)。

这几乎解决了你的整个问题。剩下两部分。

首先,你只有两个字段,第二个字段可以包含空格。所以,你只需要一次拆分,而不是尽可能多。所以:

key, value = s.split(None, 1)
key = key[:-1]

接下来,你仍然有那些讨厌的冒号。但是你不需要拆分它们。至少根据你向我们展示的数据,冒号总是出现在第一个字段的末尾,前面没有空格,后面总是空格,所以你可以删除它:

{{1}}

当然,还有其他一百万种方法可以做到这一点;这只是最接近你已经尝试的那个。

答案 4 :(得分:0)

您可以使用此

string.strip().split(":")

答案 5 :(得分:0)

正则表达式并不是这里工作的最佳工具。正如其他人所说,使用str.strip()str.split()的组合是可行的方法。这是一个单行:

>>> data = '''\n\tName: John Smith
... \n\t  Home: Anytown USA
... \n\t    Phone: 555-555-555
... \n\t  Other Home: Somewhere Else
... \n\t Notes: Other data
... \n\tName: Jane Smith
... \n\t  Misc: Data with spaces'''
>>> {line.strip().split(': ')[0]:line.split(': ')[1] for line in data.splitlines() if line.strip() != ''}
{'Name': 'Jane Smith', 'Other Home': 'Somewhere Else', 'Notes': 'Other data', 'Misc': 'Data with spaces', 'Phone': '555-555-555', 'Home': 'Anytown USA'}