#regex #vi #substitution
Вопрос:
Мне нужно изменить файл SQL с помощью vi, чтобы удалить столбцы, которые мы не используем. Поскольку у нас много данных, я использую опцию поиска и замены с шаблоном регулярного выражения.
Например, у нас есть :
(1,2956,2026442,4,NULL,NULL,'ZAC DU BOIS DES COMMUNES','',NULL,NULL,'Rue DU LUXEMBOURG',NULL,
'9999','EVREUX',NULL,1,'27229',NULL,NULL,NULL,NULL,NULL,' Rue DU LUXEMBOURG, 9999 EVREUX',NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2020-07-08 16:34:40',NULL,NULL)
Итак, у нас 40 колонок, и я оставляю 13. Мое регулярное выражение таково :
(1),2,(3),4-5,(6-14),15-22,(23),24-39,(40)
:%s/((.{-}),.{-},(.{-}),.{-},.{-},(.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-}),.{-},
.{-}, .{-},.{-},.{-},.{-},.{-},.{-},(.{-}),.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-},.{-},
.{-},.{-},.{-},.{-},.{-},(.{-}))/(1,2,3,4,5)/g
Я заключаю в скобки части, которые меня интересуют, заключая их в скобки (я получаю только значения в скобках в строке над моим регулярным выражением ). Затем с помощью замены я восстанавливаю эти группы.
Так что обычно мой результат должен быть :
(1,2026442,NULL,'ZAC DU BOIS DES COMMUNES','',NULL,NULL,'Rue DU LUXEMBOURG',NULL,
'9999','EVREUX',' Rue DU LUXEMBOURG, 9999 EVREUX',NULL)
Но потому что внутри ' Rue DU LUXEMBOURG, 9999 EVREUX'
есть запятая (,). Моим результатом станет :
(1,2026442,NULL,'ZAC DU BOIS DES COMMUNES','',NULL,NULL,'Rue DU LUXEMBOURG',NULL,'9999','EVREUX',' Rue DU LUXEMBOURG',NULL,NULL)
Может ли мне помочь кто-нибудь, кто хорошо разбирается в регулярных выражениях ? заранее спасибо. Если я не был ясен, скажите мне тоже, я постараюсь объяснить лучше в следующий раз.
Комментарии:
1. Каково здесь правило? Как вы можете описать контекст, в котором запятая должна быть «пропущена»? Могут ли другие поля содержать «дикие» запятые?
2. в этом конкретном случае нам нужно, чтобы запятая оставалась, потому что она принадлежит столбцу varchar. На самом деле, дикая запятая появляется только в строке.
Ответ №1:
Я предлагаю сопоставить поля, которые могут быть строками, с %('[^']*'|w*)
шаблоном, то есть группой без захвата, которая находит либо '
ноль или более не- '
s, а затем '
символ, либо любой ноль или более буквенно-цифровых символов.
Кроме того, использование групп без захвата (в Vim это %(...)
в very magic
режиме или %(...)
в обычном режиме) и very magic
режиме может помочь сократить шаблон.
Весь узор будет выглядеть так
:%s/v(([^,]*),[^,]*,([^,]*),[^,]*,[^,]*,(%('[^']*'|w*)%(,%('[^']*'|w*)){8})%(,%('[^']*'|w*)){8},('[^']*'|w*)%(,%('[^']*'|w*)){16},([^,]*))/(1,2,3,4,5)/g
Смотрите демонстрационную версию регулярного выражения, преобразованную в регулярное выражение PCRE.
Обратите внимание, что некоторые поля, которые не являются строками [^,]*
, сопоставляются с нулем или более символов, отличных от запятой. %(,%('[^']*'|w*)){8}
Подобные шаблоны соответствуют (здесь) 8 вхождениям последовательности ,
символов '...'
подстрока или нулю или более символов слов.