Мне нужно регулярное выражение, которое может отделять строку, например:
1st, 2nd=second, "3rd=third","4th = forth",,"6th=\"this, is, the, sixth\""
в
1st // not surrounded
2nd=second // not surrounded
3rd=third // surrounded
4th = forth // surrounded, keep the blank in the middle
// empty string
6th = "this, is, the, sixth" // the scaped dbl-quotes and commas in the middle should be kept
обратите внимание: если в разделах нет запятых или двойных кавычек, они могут быть заключены или не заключены в окружение, но если в них есть специальные символы, они должны быть заключены в окружение, а двойные кавычки должны быть заключены в обратную косую черту. Кроме того, следует сохранить пустые значения (например, пятое).
Будем благодарны за любую помощь.
Может быть, что-то вроде (?|"([^\\"]*(?:\\.[^\\"]*)*)"|([^,]+|(?<=,)|^ (?=,))) (получите снимки первой группы, \n
в демо-версии предназначен только для многострочной витрины)
Это простое сканирование, если вы не используете регулярные выражения. Начни с начала. Найдите следующую запятую или цитату. Если вы нашли цитату, найдите следующую цитату и пропустите последующую запятую. Повторяйте до готовности. Есть ли причина, по которой вы хотите усложнить задачу? <g> Регулярные выражения почти никогда не являются правильным решением проблемы синтаксического анализа. За последние десять лет я видел только два вопроса по SO, где регулярное выражение могло бы быть хорошим решением; Я видел десятки случаев, когда это было определенно намного сложнее, чем просто написание очевидного кода.
@PeteBecker: одно небольшое дополнение: вы можете встроить двойную кавычку в строку, используя две подряд, поэтому что-то вроде "He said: ""hi, my name is Jerry"""
— это одна строка, содержащая две двойные кавычки (но да, во всяком случае, это делает регулярное выражение еще более сложным, в то время как мало влияет на простой код).
CSV общего назначения значительно сложнее читать, чем думают люди, если только вы не введете ограничения (например, отсутствие двоичных данных в полях или переводы строк в полях, или требование только варианта подмножества и т. д.). Тем не менее, (относительно простой) автомат — лучший способ создать программу чтения CSV. И тем не менее, лучше всего найти библиотеку для чтения CSV. Их довольно много как для C, так и для C++.
@Сэм, я пропустил необязательное пространство до и после цитируемых частей. Если такое возможно, лучше используйте (?|\h*"([^\\"]*(?:\\.[^\\"]*)*)"\h*|([^,] +|(?<=,)|^(?=,))) (я добавил \h*
к своему последнему шаблону в соответствующих позициях для любого количества горизонтального пространства)
@bobblebubble, твой ответ выглядит довольно хорошо. Мне бы хотелось, чтобы люди не так быстро закрывали вопрос (особенно, когда то, что они видят, не решает всех проблем), чтобы я мог принять ваш ответ.
@WiktorStribiżew Связанная цель-дубликат предназначена не для кавычек с обратной косой чертой, а для двойных двойных кавычек, а также для разделения, а не сопоставления. Однако я снова открыл, чтобы опубликовать свой ответ.
Для предоставленных вами образцов будет достаточно следующего регулярного выражения.
(?|\h*"([^\\"]*(?:\\.[^\\"]*)*)"\h*|([^,]+|(?<=,)|^(?=,)))
Посмотрите эту демонстрацию по адресу regex101 (символ \n
в демо предназначен только для многострочной витрины)
Он использует группу сброса ветки для захвата нужных частей той же первой группой, которая поддерживается PCRE и даже регулярным выражением повышения (добавленным в грамматику ECMAScript в версии 1.42).
С помощью этого шаблона охватываются следующие случаи (чередуются, приоритет слева направо)
\h*"([^\\"]*(?:\\.[^\\"]*)*)"\h*
захватывать то, что находится внутри цитируемых частей, окруженных \h*
любым количеством горизонтального пространства, содержащее любое количество экранированных кавычек.[^,]+
части без кавычек: Один или несколько символов, не являющихся запятой.(?<=,)
все оставшиеся пустые места, которым предшествует запятая (просмотр назад).^(?=,)
если в начале ^ начала строки/строки есть пустое место, например. ,a
Обычно рекомендуется использовать csv-парсер, если он доступен в вашей среде.
Не используйте регулярное выражение для анализа CSV. Регулярное выражение для разделения CSV и Можно ли определить формат CSV с помощью регулярного выражения?