У меня есть такая строка:

s = "XIDJIJFHD8","Gothika","a0KU000000JMYCrMAP","USA","English","Sub & Audio","VOD","SD","01/01/2011 00:00:00.000000","12/31/2049 00:00:00.000000",,"Confirmed",,,,"Feature",,"2003-11-21","2004-03-23",,"R","for violence, brief language and nudity.","2024863","6000008953",,,"10.5240/A6FC-02AE-8093-3B05-6240-T","10.5240/D052-B470-0D01-25DF-DA91-4","2024863_6000008953","idwb:2024863_6000008953","CA-0000950613"

Мне нужно преобразовать его в «разделенный трубкой». Поля заключаются в кавычки ", хотя, если поле пустое, в нем ничего не будет. Число | в окончательном выводе должно быть 31. Вот что у меня есть:

re.sub(r'(\,|\")(,)(,|\")', '|', s)

Однако длина приведенного выше составляет всего 23. Каким будет правильное регулярное выражение?

Или, что еще лучше, я мог бы просто сделать это прямо в модуле csv. Что-то вроде:

string_with_pipes = csv.write(s, delimiter="|")

Обратите внимание, что я просто хочу получить измененную строку, а не сохранять файл.

1
David542 3 Янв 2018 в 06:35

2 ответа

Лучший ответ

Нет необходимости в регулярных выражениях. Вы можете сделать это с помощью комбинации csv.reader() и csv.writer(), используя временный буфер, для которого мы будем использовать StringIO:

import csv
from StringIO import StringIO


s = '"XIDJIJFHD8","Gothika","a0KU000000JMYCrMAP","USA","English","Sub & Audio","VOD","SD","01/01/2011 00:00:00.000000","12/31/2049 00:00:00.000000",,"Confirmed",,,,"Feature",,"2003-11-21","2004-03-23",,"R","for violence, brief language and nudity.","2024863","6000008953",,,"10.5240/A6FC-02AE-8093-3B05-6240-T","10.5240/D052-B470-0D01-25DF-DA91-4","2024863_6000008953","idwb:2024863_6000008953","CA-0000950613"'

reader = csv.reader([s])

buffer = StringIO()
writer = csv.writer(buffer, delimiter="|")
writer.writerows(reader)

buffer.seek(0)
print(buffer.getvalue())

Печать:

XIDJIJFHD8|Gothika|a0KU000000JMYCrMAP|USA|English|Sub & Audio|VOD|SD|01/01/2011 00:00:00.000000|12/31/2049 00:00:00.000000||Confirmed||||Feature||2003-11-21|2004-03-23||R|for violence, brief language and nudity.|2024863|6000008953|||10.5240/A6FC-02AE-8093-3B05-6240-T|10.5240/D052-B470-0D01-25DF-DA91-4|2024863_6000008953|idwb:2024863_6000008953|CA-0000950613
2
alecxe 3 Янв 2018 в 22:29

Последовательные запятые включаются в одно совпадение.

Вам нужно регулярное выражение, которое не включает их в замену, но гарантирует, что они есть

re.sub(r'(?<=[,"])(,)(?=[,"])', '|', s)

Это использует просмотр вперед и назад для проверки наличия, или "без их замены.

  1. (,) Соответствует запятой
  2. (?<=[,"]) Сразу после него ставится запятая или двойная кавычка
  3. (?=[,"]) Сразу после него следует запятая или двойная кавычка

(? в первой и третьей группах гарантируют, что эти группы не будут включены в замену

1
ruaridhw 3 Янв 2018 в 03:54