web-dev-qa-db-ja.com

改行、タブ、およびいくつかのスペースで分割された文字列

私はやや不規則なデータのセットで文字列分割を実行しようとしています:

\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

これを後でコロン:で分割するTuple/dictに変換したいのですが、最初に余分な空白をすべて削除する必要があります。正規表現が最良の方法だと思いますが、うまくいくものを見つけることができないようです。以下は私の試みです。

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

。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']]
78
Martijn Pieters
>>> 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'}
>>>
7
Joran Beasley

1つの正規表現ストーンで2羽の鳥を殺すことができます。

>>> 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')]
>>> 
5
georg

ドキュメント for str.split

Sepが指定されていない場合、またはNoneの場合、異なる分割アルゴリズムが適用されます:連続する空白の実行は単一のセパレーターと見なされ、文字列の先頭または末尾に空白がある場合、結果には開始または終了に空の文字列は含まれません。その結果、空の文字列または空白だけで構成される文字列をNone区切り文字で分割すると、[]が返されます。

言い換えると、splitに何を渡して'\n\tName: Jane Smith'から['Name:', 'Jane', 'Smith']、何も渡さない(またはNone)。

これで問題全体がほぼ解決します。残りの2つの部分があります。

最初に、2つのフィールドしかありませんが、2番目のフィールドにはスペースを含めることができます。したがって、できるだけ多くの分割ではなく、1つの分割のみが必要です。そう:

s.split(None, 1)

次に、これらの厄介なコロンがまだあります。ただし、それらを分割する必要はありません。少なくとも、私たちが示したデータを考えると、コロンは常に最初のフィールドの最後に表示され、前にスペースがなく、常にスペースがあるため、削除することができます。

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

もちろん、これを行う方法は他にも数百万あります。これは、あなたがすでに試みていたことに最も近いように見えるものです。

3
abarnert

これを使用できます

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

正規表現は、ここでの仕事に最適なツールではありません。他の人が言ったように、str.strip()str.split()の組み合わせを使用する方法があります。これを行う1つのライナーを次に示します。

>>> 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'}
0
Matthew Adams