vim 正则表达式替换

2021-09-23 12:17:31 +08:00
 silenceboychen

有一批类似这样的数据:

('526440130559344640','2',7,to_date('2020-11-18 00:00:00','yyyy-mm-dd hh24:mi:ss'),'0',null,null,to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')),
('526440158212390912','2',3,to_date('2020-11-18 00:00:00','yyyy-mm-dd hh24:mi:ss'),'0',null,null,to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')),

如何使用正则表达式批量将里边的 to_date 这一段,

to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')

提取出里边的日期,并替换掉这一段内容

to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')  =>  '2020-11-26 01:48:39.705'

最终数据变为下边的格式

('526440130559344640','2',7,'2020-11-18 00:00:00','0',null,null,'2020-11-26 01:48:39.705'),('526440158212390912','2',3,'2020-11-18 00:00:00','0',null,null,'2020-11-26 01:48:39.705'),
1850 次点击
所在节点    程序员
11 条回复
ruchee
2021-09-23 12:27:07 +08:00
首先你需要安装一个插件:eregex,因为 Vim 自带的正则太弱了

然后就是一个命令的事了

:%S/^[^']*?'(\d{4}.*?)'.*$/\1/g
ruchee
2021-09-23 12:30:58 +08:00
鉴于楼主又修改了帖子内容,新的命令如下

:%S/to_date\(('\d{4}[^']*?'.*?)\)/\1/g
ruchee
2021-09-23 12:35:04 +08:00
上一个命令疏忽了一点,最终解

:%S/to_date\(('\d{4}[^']*?').*?\)/\1/g
2i2Re2PLMaDnghL
2021-09-23 13:00:29 +08:00
s/todate(\('[^']\+'\),[^)]\+)/\1/g
这个是非常特化的,如果第二个字符串里有 `)` 就会出错
毕竟没人用 vim 自动化不是嘛(
自动化还是 ast 求值吧。
ETiV
2021-09-23 13:04:45 +08:00
是有多想不开才会用 vim 去做正则替换…

sed -i 可以修改原始文件,带一个参数还能备份原始文件
Kasumi20
2021-09-23 14:33:22 +08:00
就是,写一个 js 程序去处理不是很轻松吗
glacial
2021-09-23 15:00:33 +08:00
```java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
public static void main(String[] args) {
final String regex = "to_date\\((.*?),(.*?)\\)";
final String string = "('526440130559344640','2',7,to_date('2020-11-18 00:00:00','yyyy-mm-dd hh24:mi:ss'),'0',null,null,to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')),\n"
+ "('526440158212390912','2',3,to_date('2020-11-18 00:00:00','yyyy-mm-dd hh24:mi:ss'),'0',null,null,to_date('2020-11-26 01:48:39.705','yyyy-mm-dd hh24:mi:ss')),";
final String subst = "$1";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("替换结果: " + result);
}
}
```
HiHi
2021-09-23 19:43:08 +08:00
%s/to_date(\('[^']*'\),[^)]*)/\1/g
jaredyam
2021-09-23 22:09:19 +08:00
随便一个脚本语言写两句也没那么费事吧
jaredyam
2021-09-23 22:58:54 +08:00
刚才测试了一下 sed,似乎符合你的预期:

sed -E 's/to_date\(([^,]*),([^,)]*)\)/\1/g' <text>

如果没问题就加个-i,inplace 操作
gy0624ww
2021-09-24 09:42:05 +08:00
其实楼主就是想问正则吧。sed vim 和脚本 都是正则的不同调用方式

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/803602

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX