Строка разделена на новую строку, вкладку и некоторое количество пробелов
Я пытаюсь выполнить разделение строк на несколько нерегулярных данных, которые выглядят примерно так:
\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 *')
Ответы
Ответ 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'}