40

次のような不規則なデータのセットに対して文字列分割を実行しようとしています。

\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 *')
4

7 に答える 7

84

.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']]
于 2012-09-21T15:56:07.930 に答える
7
>>> 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'}
>>>
于 2012-09-21T16:01:14.790 に答える
5

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')]
>>> 
于 2012-09-21T16:03:04.393 に答える
5

次のドキュメントを見るとstr.split

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

splitつまり、に到達'\n\tName: Jane Smith'するために何を渡すかを理解しようとしている場合は、['Name:', 'Jane', 'Smith']何も渡さない(または何も渡さない)だけです。

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

まず、フィールドは2つしかなく、2番目のフィールドにはスペースを含めることができます。したがって、可能な限り多くではなく、1つの分割のみが必要です。それで:

s.split(None, 1)

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

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

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

于 2012-09-21T17:43:51.823 に答える
0

あなたはこれを使うことができます

string.strip().split(":")
于 2012-09-21T15:59:37.067 に答える
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'}
于 2012-09-21T16:05:55.657 に答える
0

改行(\ n)とタブ(\ t)で文字列を分割する必要がありました。私がしたことは、最初に\nを\tに置き換えてから、\tで分割することでした

example_arr = example_string.replace("\n", "\t").split("\t")
于 2021-12-08T07:17:45.113 に答える