用 string.replace(regex, value) 替换变量名

replace variable names with string.replace(regex, value)

尝试做我认为相当简单的字符串替换,但结果比我想象的要复杂。

如果我有这样的字符串

months + 3 + (startmonths * 3) + months - (months*7) + (monthsend*5)

为了清楚起见,我正在解析的 "formula" 是用户提供的,并且可以包含用户可以想出的任何一系列变量名称和运算符 (+*/-) 和括号。我需要做的是首先用数字替换变量,然后计算结果表达式。,

我正在寻找的是如何使用 string.replace 函数替换所有出现的月份,例如“12”。

所以希望函数的输出是

 12 + 3 + (startmonths * 3) + 12 - (12*3) + (monthsend*5)"

似乎我需要一个正则表达式来避免替换 "startmonths" 之类的字符串,我可能觉得它实际上不可能在 javascript 正则表达式中执行,因为 "lookbehinds"在现代浏览器中很少受支持。

我试过使用 [^A-Za-z9-9_](months)(?:[^A-Za-z0-9_]) 但是它捕获了 'months' 前后的字符,所以我不能将它用作 string.replace 的参数。

是否有一些解决方法,或者我是否必须忘记替换功能并使用查找和拼接等 "by hand"?

这似乎不需要回顾或回顾就可以工作:

let regExMonth = /\bmonths\b/gm;
let str = "months + 3 + (startmonths * 3) + months - (months*7) + (monthsend*5)";

str = str.replace(regExMonth, "12");
console.log(str);

来自 regexr.com 的屏幕截图:

您说得对,后视并非在任何地方都有效。但是,他们确实在 Chrome 工作,并且很快就会在 Firefox 工作。 Look-behinds 是在 2018 规范中添加的,所以很遗憾,到 2020 年它们还没有在这里普遍存在。

在支持回溯的地方,我会像这样同时使用 "negative look-behind" 和 "negative look-ahead":

(?<![A-Za-z0-9_])(months)(?![A-Za-z0-9_])
上面的

Shorthand 将是:

(?<![\w])(months)(?![\w])

来自 regexr.com 的屏幕截图:

你可以同时使用负前瞻和后视

const regex = /(?<![\w+])(months)(?![\w+])/gm;
const str = `months + 3 + (startmonths * 3) + months - (months*7) + (monthsend*5)`;
const subst = `12`;

const result = str.replace(regex, subst);
console.log('Substitution result: ', result);

我可以建议(^|[^a-z])month

解释:

(^|[^a-z]) - 匹配字符串的开头 ^ 或(由于交替 |)antyhing,但由于否定字符 class [^a-z] 导致的字母除外,最后,将其存储在第一个捕获组中。

month = 按字面意思匹配 month

Demo

编辑:小更正:(^|[^a-z])月($|[^a-z])

$- 匹配字符串结尾

将其替换为 2 - </code> - 第一个 cuptruing 组,<code> - 第二个捕获组