javascript 如何仅在字符串内的某个位置替换匹配项?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6843441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I replace a match only at a certain position inside the string?
提问by ruslan.savenok
So, I have a function which has two params: string and match index to replace and i need to replace only match with that index. How can i do that?
所以,我有一个函数,它有两个参数:要替换的字符串和匹配索引,我只需要用该索引替换匹配。我怎样才能做到这一点?
Example:
例子:
replace('a_a_a_a_a', 1)
Result:
结果:
a__a_a_a
回答by jAndy
Could look like:
可能看起来像:
var mystr = 'a_a_a_a_a';
function replaceIndex(string, at, repl) {
return string.replace(/\S/g, function(match, i) {
if( i === at ) return repl;
return match;
});
}
replaceIndex(mystr, 2, '_');
The above code makes usage of the fact, that .replace()
can take a funarg
(functional argument) as second parameter. That callback is passed in the current match of the matched regexp pattern and the indexfrom that match (along with some others which we are not interested in here). Now that is all information we need to accomplish your desired result. We write a little function wish takes three arguments:
上面的代码利用了一个事实,即.replace()
可以将funarg
(功能参数)作为第二个参数。该回调在匹配的正则表达式模式的当前匹配项和该匹配项的索引(以及我们在这里不感兴趣的其他一些)中传递。现在这就是我们完成您想要的结果所需的所有信息。我们写了一个小函数 Wish 需要三个参数:
- the string to modify
- the index we wish to change
- the replacement character for that position
- 要修改的字符串
- 我们希望更改的索引
- 该位置的替换字符
回答by Shadow Wizard is Ear For You
For those like me who find regex to be cryptic, here is "pure JavaScript" way as well:
对于像我这样觉得正则表达式很神秘的人,这里也是“纯 JavaScript”方式:
function CustomReplace(strData, strTextToReplace, strReplaceWith, replaceAt) {
var index = strData.indexOf(strTextToReplace);
for (var i = 1; i < replaceAt; i++)
index = strData.indexOf(strTextToReplace, index + 1);
if (index >= 0)
return strData.substr(0, index) + strReplaceWith + strData.substr(index + strTextToReplace.length, strData.length);
return strData;
}
Usage:
用法:
var mystr = 'a_a_a_a_a';
var newstr = CustomReplace(mystr, "_", "__", 2); //replace the second appearance
Live test case: http://jsfiddle.net/tXx5n/2/
现场测试用例:http: //jsfiddle.net/tXx5n/2/
回答by sergio
Javascript match
returns an array, in case of multiple matches, so you could so something like this:
match
如果有多个匹配项,Javascript 会返回一个数组,因此您可以这样做:
var string = "....";
var patt1 = /..../gi;
var results = string.match(patt1);
var newString = results.splice(i, i).join();
Instead of using a match, you could use split
instead in your specific case:
您可以split
在特定情况下使用,而不是使用匹配:
var results = string.split("_");
var newString = results.splice(i, i).join("_");
It depends on how your input data can vary and where you need to do the split/match (that is why I did not specify any regex above, the split example is complete)...
这取决于您的输入数据如何变化以及您需要在何处进行拆分/匹配(这就是我没有在上面指定任何正则表达式的原因,拆分示例已完成)...
回答by rajani
Use regex match with g flag var str="test string".match(/t/g) output would be array of matched strings in this case "t" [t,t,t]
使用正则表达式匹配 g 标志 var str="test string".match(/t/g) 在这种情况下输出将是匹配字符串的数组 "t" [t,t,t]
回答by Tigregalis
You need to use the function parameter of the replace
function, and also maintain an index (i
) of matches.
您需要使用的功能参数replace
的功能,同时也维护索引(i
)的比赛。
function replaceAt(string, replaceThis, replaceWith, at) {
let i = 0;
if (Array.isArray(at)) {
return string.replace(replaceThis, (match, offset) => at.includes(i++) ? replaceWith : match)
} else if (Number.isInteger(at)) {
return string.replace(replaceThis, (match, offset) => i++ === at ? replaceWith : match)
} else {
return string;
}
}
// usage:
console.log(replaceAt("aaaaabcde", /a/g, ".", [2, 0])); // ".a.aaabcde"
console.log(replaceAt("aaaaabcde", /a/g, ".", 2)); // "aa.aabcde"
String.prototype.replaceAt = function(replaceThis, replaceWith, at) {
let string = this, i = 0;
if (Array.isArray(at)) { // e.g. console.log("aaaaabcde".replaceAt(/a/g, ".", 2)); => "aa.bcde"
return string.replace(replaceThis, (match, offset) => at.includes(offset) ? replaceWith : match)
} else if (Number.isInteger(at)) { //e.g. console.log("aaaaabcde".replaceAt(/a/g, ".", [2, 0])); => ".a.bcde"
return string.replace(replaceThis, (match, offset) => offset === at ? replaceWith : match)
} else {
return string;
}
}
// usage:
console.log("aaaaabcde".replaceAt(/a/g, ".", [2, 0])); // ".a.aaabcde"
console.log("aaaaabcde".replaceAt(/a/g, ".", 2)); // "aa.aabcde"
function replaceExceptAt(string, replaceThis, replaceWith, at) {
let i = 0;
if (Array.isArray(at)) { // e.g. console.log(replaceExceptAt("aaaaabcde", /a/g, ".", 2); => "..a..bcde"
return string.replace(replaceThis, (match, offset) => !at.includes(i++) ? replaceWith : match)
} else if (Number.isInteger(at)) { //e.g. console.log(replaceExceptAt("aaaaabcde", /a/g, ".", [2, 0])); => "a.a..bcde"
return string.replace(replaceThis, (match, offset) => i++ !== at ? replaceWith : match)
} else {
return string;
}
}
// usage:
console.log(replaceExceptAt("aaaaabcde", /a/g, ".", [2, 0])); // "a.a..bcde"
console.log(replaceExceptAt("aaaaabcde", /a/g, ".", 2)); // "..a..bcde"
String.prototype.replaceExceptAt = function(replaceThis, replaceWith, at) {
let string = this, i = 0;
if (Array.isArray(at)) { // e.g. console.log("aaaaabcde".replaceExceptAt(/a/g, ".", 2); => "..a..bcde"
//return string.replace(replaceThis, (match, offset) => !at.includes(offset) ? replaceWith : match)
return string.replace(replaceThis, (match, offset) => !at.includes(i++) ? replaceWith : match)
} else if (Number.isInteger(at)) { //e.g. console.log(replaceAt("aaaaabcde", /a/g, ".", [2, 0])); => "a.a..bcde"
return string.replace(replaceThis, (match, offset) => i++ !== at ? replaceWith : match)
} else {
return string;
}
}
// usage:
console.log("aaaaabcde".replaceExceptAt(/a/g, ".", [2, 0])); // "a.a..bcde"
console.log("aaaaabcde".replaceExceptAt(/a/g, ".", 2)); // "..a..bcde"