代码之家  ›  专栏  ›  技术社区  ›  Pavel_K

调用函数以用regexp替换某些子字符串时出现问题

  •  1
  • Pavel_K  · 技术社区  · 5 年前

    我有这样一个字符串(这是一个问题的例子):

    let s = `import {
        A,
        B
    } from 'moduleA';
    import {
        C,
        D
    } from 'moduleB';`;
    

    let regExpStr = "^import [\\s\\S\\w]* from '(moduleA|moduleB)';";
    let regExp = new RegExp(regExpStr, "gm");
    let data = s.replace(regExp, function(param, p1, p2) {
        return param.replace(p1, "modified " + p1);
    });
    console.log(data);
    

    这是输出:

    import {
        A,
        B
    } from 'moduleA';
    import {
        C,
        D
    } from 'modified moduleB';
    

    如你所见,我只修改了 moduleB moduleA

    1 回复  |  直到 5 年前
        1
  •  2
  •   ggorlen Hoàng Huy Khánh    5 年前

    贪婪的 * 使regex捕获整个字符串,只替换最后一个模块。使用非贪婪量词 *? 使regex能够匹配 import { ... } from 'moduleN' 整个字符串的模式:

    let s = `import {
        A,
        B
    } from 'moduleA';
    import {
        C,
        D
    } from 'moduleB';`;
    
    let regExpStr = "^import [\\s\\S\\w]*? from '(moduleA|moduleB)';";
    let regExp = new RegExp(regExpStr, "gm");
    let data = s.replace(regExp, function(param, p1, p2) {
        return param.replace(p1, "modified " + p1);
    });
    console.log(data);

    我还鼓励使用regex literal和美元符号捕获组引用来简化代码:

    const s = `import {
        A,
        B
    } from 'moduleA';
    import {
        C,
        D
    } from 'moduleB';`;
    
    const pattern = /^(import [\s\S\w]*? from ')(moduleA|moduleB)(';)/gm;
    const data = s.replace(pattern, "$1modified $2$3");
    console.log(data);