2016-08-01 6 views
-1

TL; DR:Линия разделения с экранированными разделителями в Python

line = "one|two|three\|four\|five" 
fields = line.split(whatever) 

для того, что значение whatever делает:

fields == ['one', 'two', 'three\|four\|five'] 

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

Например, одна строка данных в этом файле может иметь представление массива из ['one', 'two', 'three\|four\|five'], и это будет представлено в файле, как one|two|three\|four\|five

У меня нет никакого контроля над файлом. Я не могу предварительно обработать файл. I имеют, чтобы сделать это в одном расколе.

Мне в конечном итоге нужно разделить каждую строку этого файла на отдельные поля, но эта обратная косая черта оказывается всевозможной проблемой. Сначала я попытался использовать негативный прогноз, но есть какая-то аркана, окружающая строки python и двойные экранированные символы, которые я не понимаю, и это мешает мне понять это.

Объяснение решения оценивается, но необязательно.

+1

Напишите свой собственный парсер для учета escape-последовательностей, регулярное выражение в Python 're' не сможет его обработать. –

+0

Вы можете уточнить, каков ваш окончательный ожидаемый результат? '['one', 'two', 'three \ | four \ | five']' или '['one', 'two', 'three', 'four', 'five']'?? – Sundeep

+0

@spasic: первый. –

ответ

0

Может быть, вы можете использовать что-то вроде этого:

[^\\]\| 

где [^\\] матч любой carácter отличается от \.

+0

Нет, для этого требуется парсер. Как насчет ''one \\ | two''? Он [не соответствует] (https://regex101.com/r/fM0dF6/1), пока он должен. –

2

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

re.split(r'([^|]+[^\\])\|', line) 

который будет использовать группу символов, чтобы указать, что-либо, кроме \ с последующим | будет использоваться, чтобы сделать раскол

Это даст дополнительный пустой матч в начале списка, но, надеюсь, вы можете обойти это как

re.split(r'([^|]+[^\\])\|', line)[1:] 

Это по-прежнему зависит от проблемы с анализом, которые, по мнению Wiktor, были, конечно,

+2

Как насчет '' one \\ | two''? Он [не соответствует] (https://regex101.com/r/fM0dF6/1), пока он должен. Когда у вас есть escape-последовательности, регулярное выражение никогда не будет точным. –

+0

Хорошая точка зрения, но если по какой-то причине необходимо использовать 'split', это может быть как можно ближе к –

+1

. На самом деле я не возражаю, если проблема с кликом @ WiktorStribiżewc не выполняется. Мне не нужно бежать от персонажей побега. Мне просто нужен раскол, чтобы не распознать 'r '\ |'' как разделитель. Ваше предлагаемое решение (@EricRenouf) не будет работать, поскольку наивный раскол также будет соответствовать последнему символу в предыдущем поле, поэтому вы получите «['on', 'tw', 'three \\ | four \\ | пять ']'. Я пробовал это как в не захватной группе, так и в негативном внешнем виде, но первый фиксирует ее в любом случае, а второй ничего не фиксирует. –

Смежные вопросы