用 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
编辑:小更正:(^|[^a-z])月($|[^a-z])
$
- 匹配字符串结尾
将其替换为 2
- </code> - 第一个 cuptruing 组,<code>
- 第二个捕获组
尝试做我认为相当简单的字符串替换,但结果比我想象的要复杂。
如果我有这样的字符串
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
编辑:小更正:(^|[^a-z])月($|[^a-z])
$
- 匹配字符串结尾
将其替换为 2
- </code> - 第一个 cuptruing 组,<code>
- 第二个捕获组