Удаление пробела из 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 для разделения. Два похожих сценарии:

6 ответов


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

вы можете применить регулярное выражение '\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

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

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 параметра, шаблон, строку, которую вы хотите заменить, и строку, над которой вы хотите работать.

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


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

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

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

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

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

что касается сохранения данных, вы можете использовать модуль 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
                             ])

похоже, эта библиотека может решить эту проблему довольно хорошо: http://docs.astropy.org/en/stable/io/ascii/fixed_width_gallery.html#fixed-width-gallery

впечатляет...