簡體   English   中英

Javascript-使用全局修飾符替換失敗

[英]Javascript - Replace using global modifier fails

這是我的代碼:

str = str.replace(/(\+?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity))([%!]+)/g, function(m, $1,     $2) {
      return "(" + $1 + ")" + $2.replace(/%/g, ".percent()")
                                .replace(/!/g, ".fact()");
});
str = str.replace(/([+]?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity)|\)|\%|\!)\^([-+]?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity)|\()/g, function(m, $1, $2) {
    if ($1 == ")" && $2 == "(") {
        return (").pow(");
    }
    if ($1 == "%" && $2 == "(") {
        return ("%.pow(");
    }
    if ($1 == "!" && $2 == "(") {
        return ("!.pow(");
    }
    if ($1 == ")") {
        return (").pow(" + $2 + ")");
    }
    if ($1 == "%") {
        return ("%.pow(" + $2 + ")");
    }
    if ($1 == "!") {
        return ("!.pow(" + $2 + ")");
    }
    if ($2 == "(") {
        return ("(" + $1 + ").pow(");
    }
    return ("(" + $1 + ").pow(" + $2 + ")");
});

問題是我想替換所有出現的情況,但不會發生。

"2%" -> "(2).percent()", working
"2%%" -> "(2).percent()%", should be "(2).percent().percent()"

我使用了g修飾符,所以看不到問題所在,該如何解決?

問題是您的模式匹配某個數字"Infinity") ,后跟一個% ,但是第二個%之前沒有任何這些,因此根本不是匹配項。

似乎您希望通過在百分比前匹配)符號來從上一個替換項的結尾處選擇) ,並將其用作下一個匹配項的一部分。 正則表達式引擎不能那樣工作。 找到匹配項后,它將繼續進行下一個匹配項。

換句話說, g修飾符並不意味着“在找不到匹配項之前遞歸替換替換項”,而是“替換在原始字符串中找到的每個匹配項”。

我確定還有其他解決方案,但是您可以嘗試以下方法:

str = str.replace(/(\+?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity))(%+)/g, function(m, $1, $2) {
  return "(" + $1 + ")" + new Array($2.length + 1).join(".percent()");
});

給定您更新的問題,您可以執行以下操作:

str = str.replace(/(\+?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity))([%!]+)/g, function(m, $1, $2) {
  return "(" + $1 + ")" + $2.replace(/%/g, ".percent()")
                            .replace(/!/g, ".fact()");
});

考慮到您的第二次更新:

var re = /(\+?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity))((?:[%!]|\^[+-]?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity|\())*)/g;
str = str.replace(
  re,
  function(m, $1, $2) {
    return "(" + $1 + ")" + $2.replace(/\^([^(^%!]+)/g, ".pow($1)")
                              .replace(/\^\(/g, ".pow(")
                              .replace(/%/g, ".percent()")
                              .replace(/!/g, ".fact()");
  });

 $('#go').click(function() { var str = $("#input").val(); var re = /(\\+?(?:(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?|Infinity))((?:[%!]|\\^[+-]?(?:(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?|Infinity|\\())*)/g; str = str.replace( re, function(m, $1, $2) { return "(" + $1 + ")" + $2.replace(/\\^([^(^%!]+)/g, ".pow($1)") .replace(/\\^\\(/g, ".pow(") .replace(/%/g, ".percent()") .replace(/!/g, ".fact()"); }); $("#output").text(str); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input id="input" value="5!^3%" /><button id="go">Go</button> <div id="output" /> 

但是,在您走這條路之前,我會警告您。 看來,使用適當的解析器最好解決此問題。 查閱jison獲得一個好的資源,以幫助您構建解析器。


對於正則表達式的有限用途,我堅持我先前的警告,但是,只要您確定輸入的一般格式大致正確,並且不介意一些不必要的括號:

str = str.replace(/[+-]?(?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity)/g, "($&)")
         .replace(/%/g, ".percent()")
         .replace(/!/g, ".fact()")
         .replace(/\^/g, ".pow");

 $('#go').click(function() { var str = $("#input").val(); str = str.replace(/[+-]?(?:(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?|Infinity)/g, "($&)") .replace(/%/g, ".percent()") .replace(/!/g, ".fact()") .replace(/\\^/g, ".pow"); $("#output").text(str); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input id="input" value="(2)^2!" /><button id="go">Go</button> <div id="output" /> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM