如果后跟特定字符串,打字稿正则表达式会排除整个字符串

Typescript regex exclude whole string if followed by specific string

我一直 运行 遇到 regex 和 Typescript 的奇怪问题,在这些问题中我试图让我的表达式替换 test 的值减去第一个实例(如果后面是 test)。换句话说,替换具有 test 的前两行,但对于下面的第三行,只替换 test 的第二个值。

[test]
[test].[db]
[test].[test]

它应该看起来像:

[newvalue]
[newvalue].[db]
[test].[newvalue]

我想出了很多变体,但我认为这是一个足够简单的方法来解决它,regex101 可以证实它有效:

\[(\w+)\](?!\.\[test\])

但是当使用 Typescript(VSTS 构建中的自定义任务)时,它实际上替换了这样的值:

[newvalue]
[newvalue].[db]
[newvalue].[test]

更新: 看起来像 (test)(?!.test) 这样的正则表达式在更改用例删除方括号时会中断,这让我觉得这可能是在代码的某处。问题可能出在替换值的索引处吗?

Typescript 中的一些代码正在调用它:

 var filePattern = tl.getInput("filePattern", true);
 var tokenRegex = tl.getInput("tokenRegex", true);
 for (var i = 0; i < files.length; i++) {
            var file = files[i];
            console.info(`Starting regex replacement in [${file}]`);

            var contents = fs.readFileSync(file).toString();
            var reg = new RegExp(tokenRegex, "g");

            // loop through each match
            var match: RegExpExecArray;
            // keep a separate var for the contents so that the regex index doesn't get messed up
            // by replacing items underneath it
            var newContents = contents;
            while((match = reg.exec(contents)) !== null) {
                var vName = match[1];
                    // find the variable value in the environment
                    var vValue = tl.getVariable(vName);
                    if (typeof vValue === 'undefined') {
                        tl.warning(`Token [${vName}] does not have an environment value`);
                    } else {
                        newContents = newContents.replace(match[0], vValue);
                        console.info(`Replaced token [${vName }]`);
                    }           
                }
            }

完整代码适用于我正在使用的任务:https://github.com/colindembovsky/cols-agent-tasks/blob/master/Tasks/ReplaceTokens/replaceTokens.ts

对我来说,这个正则表达式的工作方式与您预期的一样:

\[(test)\](?!\.\[test\])

使用这样的 Typescript 代码

myString.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");

相反,您使用的正则表达式也应该替换 [db] 部分。

我试过这个代码:

class Greeter {
    myString1: string;
    myString2: string;
    myString3: string;
    greeting: string;
    constructor(str1: string, str2: string, str3: string) {
        this.myString1 = str1.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
        this.myString2 = str2.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
        this.myString3 = str3.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
        this.greeting = this.myString1 + "\n" + this.myString2 + "\n" + this.myString3;
    }
    greet() {
        return "Hello, these are your replacements:\n" + this.greeting;
    }
}

let greeter = new Greeter("[test]", "[test].[db]", "[test].[test]");

let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
    alert(greeter.greet());
}

document.body.appendChild(button);

在线游乐场here