首页 > 解决方案 > 用正则表达式替换时结果错误

问题描述

我正在使用替换函数和正则表达式替换子字符串。然而,在字符转义和替换之后,我仍然有一个额外的 '/' 字符。我对正则表达式不太熟悉,有人可以指导我。

我已经实现了在这里找到的转义字符函数:Javascript 中有 RegExp.escape 函数吗?

RegExp.escape= function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
const latexConversions = [
    ["\\cdot", "*"],
    ["\\right\)", ")"],
    ["\\left\(", "("],
    ["\\pi", "pi"],
    ["\\ln\((.*?)\)", "log($1)"],
    ["stdev\((.*?)\)", "std($1)"],
    ["stdevp\((.*?)\)", "std(\[$1\], \"uncorrected\")"],
    ["mean\((.*?)\)", "mean($1)"],
    ["\\sqrt\((.*?)\)", "sqrt($1)"],
    ["\\log\((.*?)\)", "log10($1)"],
    ["\(e\)", "e"],
    ["\\exp\((.*?)\)", "exp($1)"],
    ["round\((.*?)\)", "round($1)"],
    ["npr\((.*?),(.*?)\)", "($1!/($1-$2)!)"],
    ["ncr\((.*?),(.*?)\)", "($1!/($2!($1-$2)!))"],
    ["\\left\|", "abs("],
    ["\\right\|", ")"],
];

RegExp.escape = function (s) {
    var t = s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    return t;
};

mathematicalExpression = "\\sqrt( )"

//Problem is here
mathematicalExpression = mathematicalExpression.replace(new RegExp(RegExp.escape(latexConversions[8][0]), 'g'), latexConversions[8][1]);

//Works
mathematicalExpression2 = mathematicalExpression.replace(/\\sqrt\((.*?)\)/g, "sqrt($1)"); 

alert("what I got: "+mathematicalExpression); // "\sqrt()"
alert("Supposed to be: "+ mathematicalExpression2); // "sqtr()"

我在这里有一个活生生的例子:https ://jsfiddle.net/nky342h5/2/

标签: javascriptstringreplaceexpression

解决方案


关于字符串文字有几个误解"\\sqrt\((.*?)\)"

  1. 这个原始字符中的字符串是:\sqrt((.*?))。注意两个左括号之间没有区别:字符串文字中的反斜杠不是很有用。换句话说,"\(" === "("
  2. 两个左括号都将被转义RegExp.escape
  3. 第 1 点和第 2 点对于右括号、点、星号和问号同样适用:它们将被转义RegExp.escape

简而言之,您无法区分一个字符是作为文字还是作为正则表达式特殊符号 - 您正在转义所有这些字符,就好像它们是作为文字字符一样。

解决方案:

由于您已经在字符串中编码正则表达式特定语法(如(.*?)),因此您不妨使用正则表达式文字而不是字符串文字。

在您突出显示的情况下,而不是这样:

["\\sqrt\((.*?)\)", "sqrt($1)"]

...用这个:

[/\\sqrt\((.*?)\)/g, "sqrt($1)"]

让您的代码执行以下操作:

mathematicalExpression = mathematicalExpression.replace(...latexConversions[8]);

选择

如果由于某种原因正则表达式文字不可行,则为(.*?). 例如,使用符号µ来表示特定的正则表达式语法。

然后您的数组对将如下所示:

["\\sqrt(µ)", "sqrt($1)"],

...和代码:

mathematicalExpression = mathematicalExpression.replace(
    new RegExp(RegExp.escape(latexConversions[8][0]).replace(/µ/g, '(.*?)'), 'g'), 
    latexConversions[8][1]
);

请注意在完成工作(.*?)如何在字符串中引入。 RegExp.escape


推荐阅读