Подтвердить что ты не робот

Строка разделена на новую строку, вкладку и некоторое количество пробелов

Я пытаюсь выполнить разделение строк на несколько нерегулярных данных, которые выглядят примерно так:

\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

Я хотел бы преобразовать это в кортеж /dict, где позже буду разбиваться на двоеточие :, но сначала мне нужно избавиться от всех лишних пробелов. Я предполагаю, что регулярное выражение - лучший способ, но я не могу заставить его работать, ниже моя попытка.

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

Ответ 1

Просто используйте . 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']]

Ответ 2

>>> 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'}
>>>

Ответ 3

Вы можете убить двух птиц одним камнем регулярного выражения:

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

Ответ 4

Если вы посмотрите документацию для str.split:

Если sep не указан или None, применяется другой алгоритм разделения: пробеги последовательного пробела рассматриваются как один разделитель, и результат не будет содержать пустых строк в начале или конце, если строка имеет ведущую или конечную пробельные. Следовательно, разделение пустой строки или строки, состоящей из простого пробела с разделителем None, возвращает [].

Другими словами, если вы пытаетесь выяснить, что нужно передать split, чтобы получить '\n\tName: Jane Smith' до ['Name:', 'Jane', 'Smith'], просто ничего не пропускайте (или None).

Это почти решает всю вашу проблему. Осталось две части.

Во-первых, у вас есть только два поля, второе из которых может содержать пробелы. Таким образом, вам нужен только один раскол, а не как можно больше. Итак:

s.split(None, 1)

Затем у вас все еще есть эти досадные двоеточия. Но вам не нужно делиться ими. По крайней мере, учитывая данные, которые вы нам показали, двоеточие всегда появляется в конце первого поля без пробелов до и после него, поэтому вы можете просто удалить его:

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

Есть миллион других способов сделать это, конечно; это именно тот, который кажется самым близким к тому, что вы уже пытались.

Ответ 5

Вы можете использовать этот

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

Ответ 6

Regex на самом деле не лучший инструмент для работы здесь. Как говорили другие, использование комбинации 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'}