Я должен искать строки в файле CSV, которые заканчиваются в незавершенной, дважды заключенной в кавычки строке.
Например:
1,2,a,b,"dog","rabbit
соответствовал бы тогда как
1,2,a,b,"dog","rabbit","cat bird"
1,2,a,b,"dog",rabbit
не был бы.
У меня есть очень ограниченный опыт с регулярными выражениями, и единственная вещь, о которой я мог думать, является чем-то как
"[^"]*$
Однако это соответствует последней кавычке в конец строки.
Как это было бы сделано?
Предполагая, что кавычки не могут быть экранированы, вам нужно проверить четность кавычек (убедившись, что их число четное, а не нечетное). Для этого отлично подходят регулярные выражения:
^(([^"]*"){2})*[^"]*$
Это соответствует всем строкам с четным числом кавычек. Вы можете инвертировать результат для всех строк с нечетным числом. Или вы можете просто добавить еще одну часть ([^ "] *")
в начале:
^[^"]*"(([^"]*"){2})*[^"]*$
Точно так же, если у вас есть доступ к неохотным операторам вместо жадных, вы можете использовать более простое выражение:
^((.*"){2})*.*$ #even
^.*"((.*"){2})*.*$ #odd
Теперь, если кавычки можно избежать, это совсем другой вопрос, но подход будет аналогичным: определить четность неэкранированных кавычек.
Предполагая, что строки не могут содержать "
, вам нужно сопоставить строку с нечетным числом кавычек, например:
([^"]*("[^"]*")?)*"
Обратите внимание, что это уязвимо для DDOS-атака.
Это будет соответствовать нулю или нескольким наборам запусков без кавычек, за которыми следуют строки в кавычках.
Попробуйте следующее:
".+[^"](,|$)
Это соответствует цитате (где угодно в строке), за которой (жадно) следует что-нибудь , но другая цитата перед концом строки или запятая.
Чистый эффект заключается в том, что он будет соответствовать только строкам с висячими строками в кавычках.
Я думаю, он даже невосприимчив к «вложенным расширенным атакам» (мы действительно живем в очень опасном мире ...)
Чтобы избежать «вложенных расширений»:
egrep -v '^[^"]*("[^"]*"[^"]*)*[^"]*$' my_file