Существует одна ОГРОМНАЯ проблема со спецификациями, которые вы дали для данных. Если "|"
допустимая строка или, точнее, строка в кавычках может начинаться с канала, то если строка с отсутствующей конечной кавычкой, например "Account1
, имеет в качестве первого следующего поля в кавычках поле, начинающееся с канала, например "|Mary"
, тогда нет никакого способа определить, во всех случаях, если "|
это конец цитаты для |"Account1||||||||||||"|
или начало котировка |"|Mary"|
.
Например, используя укороченную (для удобства чтения) слегка измененную версию данных, где все строки в кавычках, начиная со второго, начинаются с конвейера и отсутствуют конечные кавычки
123|110092|ACCT|"HC Account"|"Account1||||||||||||"|Mary|||"|||||132|"|STE|504|1253
видно, что это будет неверно истолковано как
123
110092
ACCT
"HC Account"
"Account1||||||||||||"
Mary
"|||||132|"
STE
504
1253
Обратите внимание, что это проблема, используя ли регулярные выражения, Python или любой другой язык. Общая проблема случая может быть «решена», но она будет сложной и требует использования знаний о том, сколько полей существует в строке и структуре данных этих полей. (И всегда могут быть крайние случаи, оставленные без обслуживания.)
При этом решение для регулярных выражений, которое по крайней мере обнаруживает большинство случаев, когда открывающая двойная кавычка пропускает закрывающую кавычку, требует многоходового подхода, так как регулярное выражение должно захватывать весь текст от начала каждой строки до первого необработанного непревзойденного открытия цитаты. (В противном случае, как показывает ваше регулярное выражение, даже в простейших случаях обнаруживаются ложные срабатывания.)
Требуемое количество проходов - это максимальное количество полей только для открывающих кавычек для любой строки во всем файле плюс один. Прекращение обработки каждого файла требует обнаружения, когда регулярное выражение не вносит никаких изменений в файл.
Это простейшее регулярное выражение, которое будет работать в большинстве случаев:
Capturing Group 1 Capturing Group 2 (All previous valid fields) (Unclosed opening quote) __________________________|_________________________ | | || | ^((?:(?:(?!")[^|\r\n]*|"[^"\r\n]*"(?=$|\|))(?:$|\|))*+)(") |____________| |_________________| |______| | | | Unquoted field OR Quoted field EOL or hypen delimiter
Используйте это с этой строкой замены:
$1\\$2
Поскольку замещающая строка выходит за пределы открытых кавычек, в результате чего первый символ обработанного поля больше не является кавычкой, регулярное выражение пропустит поле при последующих проходах.
Обратите внимание, что, к сожалению, это регулярное выражение будет игнорировать открытые только для кавычек поля, если следующее следующее поле в кавычках начинается с канала. Кроме того, если следующее следующее поле в кавычках также заканчивается каналом, то для дальнейших следующих кавычек также будет генерироваться ложное срабатывание.
Как побочный эффект своей простоты, регулярное выражение также будет игнорировать кавычки, появляющиеся в середине поля. (Это может или не может быть проблемой.)
Регулярное выражение можно улучшить, чтобы оно работало, даже если следующее поле в кавычках начинается с канала:
^((?:(?:(?!")[^|\r\n]*|"[^"\r\n]*"(?:(?=$)|(?=\|)(?!(?:\|[^|"\r\n]*)+[^|\r\n]")))(?:$|\|))*+)(") |____________________________________________| | Modified lookahead to make sure that the following | is not the first char of a properly quoted field
Тем не менее, невозможно легко исправить это, чтобы работать для случая, когда следующее следующее указанное в кавычках поле и начинается и заканчивается трубой.