• 请不要在回答技术问题时复制粘贴 AI 生成的内容
silenceboychen
V2EX  ›  程序员

vim 正则表达式替换

  •  
  •   silenceboychen · Sep 23, 2021 · 2561 views
    This topic created in 1691 days ago, the information mentioned may be changed or developed.

    有一批类似这样的数据:

    ('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'),
    
    11 replies    2021-09-24 09:42:05 +08:00
    ruchee
        1
    ruchee  
       Sep 23, 2021
    首先你需要安装一个插件:eregex,因为 Vim 自带的正则太弱了

    然后就是一个命令的事了

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

    :%S/to_date\(('\d{4}[^']*?'.*?)\)/\1/g
    ruchee
        3
    ruchee  
       Sep 23, 2021   ❤️ 1
    上一个命令疏忽了一点,最终解

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

    sed -i 可以修改原始文件,带一个参数还能备份原始文件
    Kasumi20
        6
    Kasumi20  
       Sep 23, 2021
    就是,写一个 js 程序去处理不是很轻松吗
    glacial
        7
    glacial  
       Sep 23, 2021
    ```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
        8
    HiHi  
       Sep 23, 2021
    %s/to_date(\('[^']*'\),[^)]*)/\1/g
    jaredyam
        9
    jaredyam  
       Sep 23, 2021
    随便一个脚本语言写两句也没那么费事吧
    jaredyam
        10
    jaredyam  
       Sep 23, 2021
    刚才测试了一下 sed,似乎符合你的预期:

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

    如果没问题就加个-i,inplace 操作
    gy0624ww
        11
    gy0624ww  
       Sep 24, 2021
    其实楼主就是想问正则吧。sed vim 和脚本 都是正则的不同调用方式
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   944 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 21:29 · PVG 05:29 · LAX 14:29 · JFK 17:29
    ♥ Do have faith in what you're doing.