2009-08-11 2 views
2

Ich habe folgende JavaScript (die Räume in den <P> s sind nicht brechend):Wie wiederhole ich die Matches eines Regex in einem Replace in Javascript?

var html = '...<li>sub 2</li></ol></li></ol>\n\ 
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subsub 1</p>\n\ 
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ii.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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>"; 
    }); 
}); 

Die alert() ‚s Ausgang:

<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> 

was hier ich hoffte, dass es sein würde:

<ol> 
<li>subsub 1</li> 
<li>subsub 2</li> 
</ol></li> 

Wie kann ich jedes Match im $1 korrekt durchlaufen?

Update: vereinfachten Muster und passendes Beispiel:

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 
+0

können Sie Ihren Code, regex nicht vereinfachen, und Markup, damit die Menschen das Problem verstehen leichter und Sie deshalb mehr helfen? (Keine rhetorische Frage) –

+0

Ich habe eine einfachere Version hinzugefügt, macht das mehr Sinn? – travis

+0

Warte, "kannst du nicht ..." hast du gesagt, dass ich es schon zu sehr vereinfacht habe? – travis

Antwort

1

Hier ist die Lösung, die ich mit aufkommen, aber es scheint nicht sehr effizient zu sein:

$(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>"; 
    }); 
}); 

... oder für das einfachere Beispiel oben:

$(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; 
    }); 
}); 

Handeln einer .replace() Substitution innerhalb einer Schleife eines .match() array, insid e einer benutzerdefinierten .replace() Funktion scheint nur nicht wie es ist sehr wirtschaftlich. Es gibt mir zwar die Ausgabe, nach der ich gesucht habe.

4

Das aktualisierte Beispiel nur gegeben haben würde passen "3" nicht "13467", wie Sie beschrieben. Wenn Sie Ihre Regexp ändern, um einen globalen Abgleich durchzuführen, würde sie "36" und immer noch nicht den "13467" zurückgeben.

Ihr erstes Beispiel gibt auch nichts aus.

Versuchen Sie nur, Übereinstimmungen mit dem regulären Ausdruck zu erhalten und die Übereinstimmungen zu durchlaufen?

Wenn ja,

var text = '1ab2cb3cd4ab5cb6cd7'; 
var matches = text.match(/(\d)/g); 
for (i=0; i<matches.length; i++) { 
    alert(matches[i]); 
} 
+0

Schließen, versuche ich durch die Spiele einer bestimmten Gruppe zu iterieren. Also für "abcdcdef" .match (/ ab (cd) + ef /) Wie durchlaufe ich mehrere Matches von $ 1? – travis

1

kann eine ziemlich Schleife Hakenmuster werden:

var text = '1ab2cb3cd4ab5cb6cd7'; 
text.match(/(\d)/g).forEach(function(element,index){ 
    console.log(element) 
}); 
Verwandte Themen