在 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$]+)
- 匹配除单词非单词字符和 $ 之外的任何内容
尝试匹配 (?:\$\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);
我正在尝试在 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$]+)
- 匹配除单词非单词字符和 $ 之外的任何内容
尝试匹配 (?:\$\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);