我必须使用 vi 修改一个 SQL 文件才能删除我们不使用的列。由于我们有很多数据,我使用带有正则表达式模式的搜索和替换选项。
例如,我们有:
(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)
擅长正则表达式的人可以帮助我吗? 提前感谢。如果我不清楚,也告诉我,下次我会尝试更好地解释。
我建议匹配字段,这些字段可以是具有%('[^']*'|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 次出现,
字符 +'...'
子字符串或零个或多个单词字符的序列。