在 JavaScript 中编写正则表达式以匹配 $ 变量前缀语法(如在 Bash 脚本中找到的)

Writing a regex in JavaScript to match $ variable prefix syntax (like found in Bash scripts)

我正在尝试在 JavaScript 中编写正则表达式来搜索多行 bash 脚本并提取所有变量名称。我似乎既不能自己弄明白,也找不到完全符合我需要的脚本。

我已经走到这一步了:

var re = /(?:^|\W)$(\w+)(?!\w)/g;
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5";
var matches = [];
while (match = re.exec(s)) {
  matches.push(match[1]);
}

这将给我 "test1"、"test3" 和 "test4"。但我也想得到 "test2" 和 "test5".

如果有一种方法可以让“\$”在字符串中出现时不匹配,那也很好。换句话说,有没有办法对文本中的“$”字符串进行转义,以便它被我的正则表达式忽略?因此,如果“\$1.00”出现在文本中,它将不会匹配“1”,就像上面的正则表达式现在所做的那样。

在此先感谢您的帮助或为我指明正确的方向。

PS 这实际上是针对 Action Script 3 的,但是任何在 JavaScript pre-ES6 中工作的东西都应该在 AS 3 中工作。

PPS 最终目标是用键值哈希中的变量替换这些匹配项。

您可以重复匹配 $(在这种情况下什么都不做)或 $\w+(在这种情况下,它是一个未转义的美元符号,表示您要匹配的变量的开头)。使用替换函数来决定是单独保留匹配项,还是替换为您想要的任何其他字符串:

const replacements = {
  test1: 'testone',
  test2: 'testtwo',
  test3: 'testthree',
  test4: 'testfour',
  test5: 'testfive'
};
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5 \.00";
const result = s.replace(
  /\$|$(\w+)/g,
  (match, g1) => match === '\$'
    ? match // replace with the matched string - in other words, leave it unchanged
    : replacements[g1]
);
console.log(result);

在较新的引擎上,您可以对反斜杠进行反向回顾,这使逻辑更容易,但它不是一个好的cross-browser解决方案,因为它只会在新环境中工作:

const replacements = {
  test1: 'testone',
  test2: 'testtwo',
  test3: 'testthree',
  test4: 'testfour',
  test5: 'testfive'
};
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5 \.00";
const result = s.replace(
  /(?<!\)$(\w+)/g,
  (_, g1) => replacements[g1]
);
console.log(result);

这个表达式

(?:\{2,}$[0-9.]+)|$([^$\s]+)

使用 non-capturing 组收集不需要的数据

(?:\{2,}$[0-9.]+)

和returns使用捕获组

所需的数据
([^$\s]+)

Demo

const regex = /(?:\{2,}$[0-9.]+)|$([^$\s]+)/g;
const str = `test $test1 testagain$test2 testyetagain $test3 $test4$test5 \\$1.00 \\\\\\$1.00

`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

正则表达式电路

jex.im 可视化正则表达式:

您可以使用这个正则表达式

(?<!\)$([^\W$]+)
  • (?<!\) - 负面回溯以避免 $ 匹配
  • $ - 匹配 $
  • ([^\W$]+) - 匹配除单词非单词字符和 $
  • 之外的任何内容

Demo

尝试匹配 (?:\$\w+)|$(\w+)。由于第一组较早开始匹配,因此会先完成匹配;但是作为 non-capturing 块,将不会返回。

var re = /(?:\$\w+)|$(\w+)/g;
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5\.00";
var matches = [];
while (match = re.exec(s)) {
  match[1] && matches.push(match[1]);
}
console.log(matches);