私はやや不規則なデータのセットで文字列分割を実行しようとしています:
\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 *')
。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']]
>>> 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'}
>>>
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')]
>>>
ドキュメント 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]
もちろん、これを行う方法は他にも数百万あります。これは、あなたがすでに試みていたことに最も近いように見えるものです。
これを使用できます
string.strip().split(":")
正規表現は、ここでの仕事に最適なツールではありません。他の人が言ったように、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'}