[英]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.