How do I loop through a regex's matches inside a replace in javascript?
10,111
Solution 1
Here's the solution that I came up with but it doesn't seem to be very efficient:
$(function () {
var nestedListFixer = /(?:<\/li><\/ol>\s*)+(?:<p>(?:&(?:nbsp|\#0*160|x0*A0);)+(?:\s[ivxlcdm]+\.)(?:&(?:nbsp|\#0*160|x0*A0);)+\s(.*?)<\/p>\s*)+(?:<ol(?:\sstyle=\"[^\"]+\")?\sstart=\"[^\"]+\">\s*)+/gi;
var nestedListItem = /<p>(?:&(?:nbsp|\#0*160|x0*A0);)+(?:\s[ivxlcdm]+\.)(?:&(?:nbsp|\#0*160|x0*A0);)+\s(.*?)<\/p>\s*/gi;
// fix nested lists
html = html.replace(nestedListFixer, function($0, $1){
var lis = ""
$.each($0.match(nestedListItem), function () {
lis += "<li>" + this.replace(nestedListItem, "$1") + "</li>\n";
});
return "<ol>\n" + lis + "</ol></li>";
});
});
...or for the simpler example above:
$(function () {
var textFixer = /(?:a)(?:b(.*?)c)+(?:d)/gi;
var textItem = /b(.*?)c/gi;
text = text.replace(textFixer, function($0, $1){
var numbers = "";
$.each($0.match(textItem), function () {
numbers += this.replace(textItem, "$1");
});
return numbers;
});
});
Doing a .replace()
substitution, inside a loop of a .match()
array, inside of a custom .replace()
function just doesn't seem like it is very economical. It does give me the output that I was looking for though.
Solution 2
A pretty loop can be using hook pattern :
var text = '1ab2cb3cd4ab5cb6cd7';
text.match(/(\d)/g).forEach(function(element,index){
console.log(element)
});
Author by
travis
Software engineer at Tenet in Rochester, NY. he/him My keybase: keybase.io/trav
Updated on June 05, 2022Comments
-
travis almost 2 years
I have the following JavaScript (the spaces in the
<P>
s are non-breaking):var html = '...<li>sub 2</li></ol></li></ol>\n\ <p> i. subsub 1</p>\n\ <p> ii. subsub 2</p>\n\ <ol start="2"> \n\ <ol start="3"> \n\ <li>sub 3</li></ol>...'; $(function () { var nestedListFixer = /(?:<\/li><\/ol>\s*)+(?:<p>(?:&(?:nbsp|\#0*160|x0*A0);)+(?:\s[ivxlcdm]+\.)(?:&(?:nbsp|\#0*160|x0*A0);)+\s(.*?)<\/p>\s*)+(?:<ol(?:\sstyle=\"[^\"]+\")?\sstart=\"[^\"]+\">\s*)+/i; html = html.replace(nestedListFixer, function($0, $1){ var lis = "" $.each($1, function () { lis += "<li>" + this + "</li>\n"; }); alert("<ol>\n" + lis + "</ol></li>"); return "<ol>\n" + lis + "</ol></li>"; }); });
The
alert()
's output:<ol> <li>s</li> <li>u</li> <li>b</li> <li>s</li> <li>u</li> <li>b</li> <li> </li> <li>2</li> </ol></li>
Here's what I hoped it would be:
<ol> <li>subsub 1</li> <li>subsub 2</li> </ol></li>
How do I correctly loop through each match in the
$1
?Update: simplified pattern and matching example:
var text = '1ab2cb3cd4ab5cb6cd7'; $(function () { var textFixer = /(?:a)(?:b(.*?)c)+(?:d)/i; text = text.replace(textFixer, function($0, $1){ var numbers = ""; $.each($1, function () { numbers += this; }); alert(numbers); return numbers; }); alert(text); }); // actual text: // 13467 // desired text: // 1234567