【问题标题】:Get exact match in string using regex and javascript使用正则表达式和 javascript 在字符串中获取完全匹配
【发布时间】:2015-02-18 23:49:52
【问题描述】:

我试图从给定的字符串中获得完全匹配,然后操作该字符串。我有一个相当大的计算器程序,你可以在这里看到:http://www.marcusparsons.com/projects/calculator。主页上还没有任何内容,原始代码很长。

我们的目标是在计算器中实现一项功能,其中数学不必作为数学对象/方法的前缀。直到我添加了一个允许用户使用“acosh()”方法(和实验方法)的功能,无论它是否在他们的浏览器中实现(ehem...IE),它一直运行良好。我遇到的问题是我现在的算法想用 aMath.cosh() 替换“acosh”,因为它在“acosh”中看到“cos”。

所以,当我将字符串“acosh(1)+cos(pi/3)”传递给它时,它变成了“aMath.cosh(1)+cos(Math.PI/3)”。

编辑:上面的字符串应该是“acosh(1)+Math.cos(Math.PI/3)”。

我是正则表达式的新手,我认为这就是我的问题所在。

示例代码如下:http://jsfiddle.net/mparson8/2ej5n3u4/4/

var $mathKeywords = ["E", "LN2", "LN10", "LOG2E", "LOG10E", "PI", "SQRT1_2", "SQRT2", "abs", "acos", "asin", "asinh", "atan", "atan2", "atanh", "cbrt", "ceil", "clz32", "cos", "exp", "expm1", "floor", "fround", "hypot", "imul", "log1p", "log10", "log2", "max", "min", "pow", "random", "round", "sin", "sinh", "sqrt", "tan", "tanh", "trunc"];

var $resultVal = "acosh(1)+cos(PI/3)".toLowerCase();
try {
//Iterate over each Math object/method
$.each($mathKeywords, function (i, val) {
    //Convert val within array to a lower case form
    var $lowerKey = val.toLowerCase();
    //The regex pattern I came up with
    var pattern = new RegExp("(^|\\W)" + $lowerKey + "($|\\W)");
    //See if pattern gives a match within $resultVal
    var $location = $resultVal.match(pattern);
    //Math keyword is found
    if ($location != null) {
        //replace the lowercase version of the math keyword with its properly cased version prepended 
        //with Math. i.e. cos becomes Math.cos and pi becomes Math.PI
        $resultVal = $resultVal.replace($lowerKey, "Math." + val);
    }
});
//Set the result element's value to an evaluation of $resultVal
//A better implementation of the eval exists within the calc program
alert($resultVal);
alert(eval($resultVal));
} catch (err) {
alert("Error: Cannot process expression due to " + err + ".");
}

感谢所有帮助! :)

【问题讨论】:

  • acosh 在您的列表中的哪个位置?
  • (^|\W)cos($|\W) 匹配 acosh;您已正确添加了单词边界,所以我不确定这是您的问题...
  • acosh 不属于列表,因为它会是数学原型的一部分,如果你尝试在 IE 中运行“acosh”,你会得到一个错误,因为它不作为数学方法的一部分存在。其他的实验方法我还没有拿出来,因为我刚刚在运行测试。
  • 马克,那个正则表达式和从代码返回的那个不一样。如果您在 $location 设置 $resultVal.match(pattern); 后显示警报,您会看到它还会返回一些额外的字符。
  • @MarcusParsons 哦...那是因为\W 匹配标点符号/运算符(例如regex101.com/r/zH9hH1/1)。你想要的是一个零宽度的断言,或者一个捕获组。只需将(^|\\W)($|\\W) 都替换为\b(或字符串中的\\b),例如regex101.com/r/pP9pT0/1

标签: javascript regex string replace match


【解决方案1】:

如果你想继续走正则表达式的道路,这似乎可行:

var $mathKeywords = ["E", "LN2", "LN10", "LOG2E", "LOG10E", "PI", "SQRT1_2", "SQRT2", "abs", "acos", "asin", "asinh", "atan", "atan2", "atanh", "cbrt", "ceil", "clz32", "cos", "exp", "expm1", "floor", "fround", "hypot", "imul", "log1p", "log10", "log2", "max", "min", "pow", "random", "round", "sin", "sinh", "sqrt", "tan", "tanh", "trunc"];

var $resultVal = "acosh(1)+cos(PI/3)".toLowerCase();
try {
    //Iterate over each Math object/method
    $.each($mathKeywords, function (i, val) {
        //Convert val within array to a lower case form
        var $lowerKey = val.toLowerCase();
        var pattern = new RegExp("\\b" + $lowerKey + "\\b", "g");
        //See if pattern gives a match within $resultVal
        var $location = $resultVal.match(pattern);
        //Math keyword is found
        if ($location != null) {
            //replace the lowercase version of the math keyword with its properly cased version prepended 
            //with Math. i.e. cos becomes Math.cos and pi becomes Math.PI
            $resultVal = $resultVal.replace(pattern, "Math." + val);
        }
    });
    //Set the result element's value to an evaluation of $resultVal
    //A better implementation of the eval exists within the calc program
    console.log($resultVal);
    console.log(eval($resultVal));
} catch (err) {
    alert("Error: Cannot process expression due to " + err + ".");
}

输出:

acosh(1)+Math.cos(Math.PI/3)

(实际上是Error: Cannot process expression due to ReferenceError: acosh is not defined.,但你明白了)


变化:

  • 使用\b 作为单词边界
  • 在替换中使用模式(带单词边界)
  • 使用g 标志替换所有次出现。

【讨论】:

  • 没有。你仍然会遇到我上面描述的问题。
  • 重新排列列表,我想我们可能会有赢家
  • @deweyredman 你不正确。单词边界\b 负责这一点。 \bcos\b 将不匹配 .acos(或 .acosh)。
  • Halcyon,这正是我所需要的。我的问题既是正则表达式,也是我需要替换的。我觉得这是一个杜!片刻。谢谢你! :)
  • 这真是一个非常好的答案。此行需要突出显示:new RegExp("\\b" + $lowerKey + "\\b", "g");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多