regex help - игнорировать символ, если он в кавычках

У нас есть веб-приложение, где вы можете ввести регулярное выражение в поле поиска, и оно возвращает совпадения из базы данных.

Вот пример того, как могут выглядеть записи базы данных. Они разделены запятыми (представьте, что каждая запись - это семья - каждая семья может содержать от 1 до n записей):

record1: "john doe"<[email protected]>;male,"jane doe"<[email protected];female
record2: "john smith"<[email protected]>
record3: "smith, jane"<[email protected]>

Что мне нужно сделать, это ввести регулярное выражение, поэтому я получаю только первую запись. В рабочем сценарии выводом будет все, вплоть до разделителя:

record1: "john doe"<[email protected]>;male
record2: "john smith"<[email protected]>
record3: "smith, jane"<[email protected]>

На самом деле, все мои попытки видеть запятую в "кузнец, джейн" как разделитель.

Как игнорировать запятую, если она в кавычках? (Для проверки на будущее, способность игнорировать запятые в одинарных кавычках тоже будет хорошей)

Я могу использовать только регулярные выражения, а не awk/sed и т. Д., А разновидность регулярных выражений - POSIX Extended.

4 ответа

Подчеркните: вам нужно детализировать вашу среду немного больше, как указано в комментариях.

Вот одна попытка моей оболочки Unix с sed
Да я знаю ты не хочешь sed, но это может помочь вам построить регулярное выражение в вашей среде.

data.txt: 
"john doe"<[email protected]>;male,"jane doe"<[email protected];female
john_doe"<[email protected]>;male,"jane doe"<[email protected];female

# sed -n 's|^\("[^"]\+"[^,]\+\).*|\1| p' data.txt 
"john doe"<[email protected]>;male

Идея регулярного выражения заключается в том, чтобы перепрыгнуть через первую пару двойных кавычек, а затем искать запятую.
Это не удастся, если нет двойных кавычек.
Его можно масштабировать для использования одинарных кавычек.

Обновление:
Ищите @ с последующим ,...

data.txt: 
"john doe"<[email protected]>;male,"jane doe"<[email protected];female
john_doe"<[email protected]>;male,"jane doe"<[email protected];female

# sed -n 's|\([^@]\+[^,]\+\),.*|\1| p' data.txt 
"john doe"<[email protected]>;male
john_doe<[email protected]>;male

Теперь вы получаете оба случая, а затем также те без названия строки или даже <> заворачивать.
Но ваша проблема в зависимости от , - перерывы для record2 и record3, где у вас есть один адрес электронной почты и без запятой. Все равно будет работать, если вы заставили , в конце каждой записи.

Вы не можете надежно сделать это с помощью регулярных выражений. Лучшее, что вы сможете сделать, это уродливый хак, основанный на куче предположений, которые гарантированно сломаются в конце концов, если вы решитесь внедрить такой код в производство. (Если вы не можете сделать это с огневой мощью полностью вооруженного и работающего движка регулярных выражений Perl, то вы, конечно, не сможете сделать это с расширенными регулярными выражениями POSIX.)

Короче говоря, чтобы надежно решить эту проблему, вам нужно будет найти какой-то способ расширить любой код, с которым вы работаете, чтобы он мог использовать библиотеку синтаксического анализа CSV, или в случае ее сбоя вам придется написать парсер

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

Используйте regex, чтобы изменить разделитель, если он заключен в кавычки с чем-то вроде tab:

Шаблон ((?:[^,"]|"[^"]*")+),
Заменить \1\ т

Затем разделить на новый разделитель

Попытка игнорировать запятую внутри кавычек проблематична, потому что запятая, которую вы хотите найти, также находится в кавычках (конечная кавычка "john doe" и открытая цитата "jane doe"). Если вы не предполагаете, что первая цитата существует, вам будет трудно сделать это различие.

Попробуйте это вместо:

^[^<]+<[^>]*>[^,\s]*

Я предполагаю, что каждая запись будет иметь <email> и любая запятая после электронного письма будет указывать новую запись. Это просто обменяет одно предположение на другое, но в моем тесте это сработало.

Другие вопросы по тегам