¿Cómo puedo recorrer unos partidos de expresiones regulares dentro de una sustitución en javascript?

StackOverflow https://stackoverflow.com/questions/1261985

Pregunta

Tengo las siguientes JavaScript (los espacios en los <P>s son de no separación):

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

La producción de la alert():

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

Esto es lo que esperaba que fuera:

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

¿Cómo correctamente bucle a través de cada partido en el $1?

Actualización: modelo simplificado y ejemplo juego:

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
¿Fue útil?

Solución 2

Aquí está la solución que se me ocurrió, pero no parece ser muy eficiente:

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

... o para el ejemplo más simple de arriba:

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

Hacer un cambio .replace(), dentro de un bucle de una matriz .match(), en el interior de una función .replace() medida solo no parece como que es muy económico. Me da la salida que estaba buscando sin embargo.

Otros consejos

El ejemplo actualizado que ha dado solamente se correspondería con "3" no "13467", como se describe. Si cambia de expresión regular para hacer juego global, volvería "36" y aún no es el "13467".

Su primer ejemplo no hace nada, ya sea de salida.

¿Está tratando de obtener coincidencias con la expresión regular y bucle a través de los partidos?

Si es así,

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

Un bucle bonito se puede utilizando patrón de gancho:

var text = '1ab2cb3cd4ab5cb6cd7';
text.match(/(\d)/g).forEach(function(element,index){
   console.log(element)
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top