Неправильный результат при замене на регулярное выражение - PullRequest
0 голосов
/ 05 июля 2019

Я заменяю подстроку, используя функцию замены и выражение регулярного выражения. Однако после побега и замены персонажа у меня все еще остается дополнительный символ «/». Я не очень знаком с регулярным выражением, может кто-то направлять меня.

Я реализовал функцию escape-символа, найденную здесь: Есть ли функция RegExp.escape в Javascript?

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/

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Существует несколько заблуждений относительно строкового литерала "\\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 выполнил свою работу.

0 голосов
/ 05 июля 2019

больше \ вместо того, чтобы убежать от всего

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

and replace the final replace with 
mathematicalExpression = mathematicalExpression.replace(new RegExp((latexConversions1[8][0]), 'g'), latexConversions1[8][1]);
...