Как мне пройти через совпадения регулярных выражений внутри замены в JavaScript? - PullRequest
2 голосов
/ 11 августа 2009

У меня есть следующий JavaScript (пробелы в <P> не ломаются):

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

Выход 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>

Вот то, на что я надеялся:

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

Как правильно выполнить цикл по каждому совпадению в $1?

Обновление: упрощенный шаблон и пример сопоставления:

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

Ответы [ 3 ]

4 голосов
/ 11 августа 2009

Обновленный пример, который вы дали, будет соответствовать только «3», а не «13467», как вы описали. Если вы измените свое регулярное выражение для глобального сопоставления, оно вернет «36», а не «13467».

Ваш первый пример тоже ничего не выводит.

Вы просто пытаетесь получить совпадения с регулярным выражением и перебрать совпадения?

Если это так,

var text = '1ab2cb3cd4ab5cb6cd7';
var matches = text.match(/(\d)/g);
for (i=0; i<matches.length; i++) {
   alert(matches[i]);
}
1 голос
/ 15 февраля 2015

Симпатичная петля может быть с использованием шаблона крючка:

var text = '1ab2cb3cd4ab5cb6cd7';
text.match(/(\d)/g).forEach(function(element,index){
   console.log(element)
});
1 голос
/ 12 августа 2009

Вот решение, которое я придумала, но оно не кажется очень эффективным:

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

... или для более простого примера выше:

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

Выполнение подстановки .replace() внутри цикла массива .match() внутри пользовательской функции .replace() не выглядит очень экономичным. Это действительно дает мне вывод, который я искал, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...