Удаление пробела из txt с помощью python

У меня есть .txt файл (очищенный как предварительно отформатированный текст с сайта), где данные выглядят следующим образом:

B, NICKOLAS                       CT144531X       D1026    JUDGE ANNIE WHITE JOHNSON  
ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS        

Я хочу удалить все лишние пробелы (они фактически представляют собой разные пробелы, а не вкладки) между столбцами. Я также хотел бы заменить его каким-то разделителем (tab или pipe с запятыми внутри данных), например:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

Посмотрел вокруг и обнаружил, что лучшие варианты используют regex или shlex для разделения. Два похожих сценария:

Ответ 1

s = """B, NICKOLAS                       CT144531X       D1026    JUDGE ANNIE WHITE JOHNSON  
ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS
"""

# Update
re.sub(r"(\S)\ {2,}(\S)(\n?)", r"\1|\2\3", s)
In [71]: print re.sub(r"(\S)\ {2,}(\S)(\n?)", r"\1|\2\3", s)
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON  
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

Ответ 2

Вы можете применить регулярное выражение '\s{2,}' (два или более пробельных символа) к каждой строке и заменить спички одним символом '|'.

>>> import re
>>> line = 'ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS        '
>>> re.sub('\s{2,}', '|', line.strip())
'ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS'

Отбрасывание любого ведущего и конечного пробела из строки перед применением re.sub гарантирует, что вы не получите символы '|' в начале и конце строки.

Ваш фактический код должен выглядеть примерно так:

import re
with open(filename) as f:
    for line in f:
        subbed = re.sub('\s{2,}', '|', line.strip())
        # do something here

Ответ 3

Как насчет этого?

your_string ='ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS'
print re.sub(r'\s{2,}','|',your_string.strip())

Вывод:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

Expanation:

Я использовал re.sub(), который принимает 3 параметра, шаблон, строку, которую вы хотите заменить, и строку, над которой хотите работать.

То, что я сделал, занимает как минимум два пространства вместе, я заменил их на | и применил его в вашей строке.

Ответ 4

Учитывая, что для разделения столбцов имеется по крайней мере два пробела, вы можете использовать это:

lines = [
'B, NICKOLAS                       CT144531X       D1026    JUDGE ANNIE WHITE JOHNSON  ',
'ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS        '
]

for line in lines:
    parts = []
    for part in line.split('  '):
        part = part.strip()
        if part:  # checking if stripped part is a non-empty string
            parts.append(part)
    print('|'.join(parts))

Вывод для ввода:

B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

Ответ 5

Похоже, что ваши данные находятся в формате "текстовая таблица".

Я рекомендую использовать первую строку, чтобы определить начальную точку и длину каждого столбца (либо вручную, либо написать script с регулярным выражением для определения вероятных столбцов), а затем написать script для повторения строк файл, нарезать строку на сегменты столбцов и применить полосу к каждому сегменту.

Если вы используете регулярное выражение, вы должны отслеживать количество столбцов и вызывать ошибку, если какая-либо заданная строка имеет больше ожидаемого количества столбцов (или другого числа, чем остальные). Разделение на два или более пространства будет разрываться, если значение столбца имеет два или более пробелов, что не только вполне возможно, но и вероятно. Текстовые таблицы, подобные этому, не предназначены для разделения на регулярное выражение, они предназначены для разделения на позиции индекса столбца.

С точки зрения сохранения данных, вы можете использовать модуль csv для записи/чтения в файл csv. Это позволит вам обрабатывать цитирование и экранирование символов лучше, чем указание разделителя. Если один из ваших столбцов имеет знак | в качестве значения, если вы не кодируете данные со стратегией, которая обрабатывает экраны или цитируемые литералы, ваш вывод будет прерываться при чтении.

Анализ текста выше выглядел бы примерно так (я вложил понимание списка с помощью скобок вместо традиционного формата, чтобы его было легче понять):

cols = ((0,34),
        (34, 50),
        (50, 59),
        (59, None),
        )
for line in lines:
    cleaned = [i.strip() for i in [line[s:e] for (s, e) in cols]]
    print cleaned

то вы можете написать его с чем-то вроде:

import csv
with open('output.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter='|',
                            quotechar='"', quoting=csv.QUOTE_MINIMAL)
    for line in lines:
        spamwriter.writerow([line[col_start:col_end].strip()
                             for (col_start, col_end) in cols
                             ])