2009-08-11 4 views
2

У меня есть следующие JavaScript (пробелы в <P> с являются неразрывный):Как прокрутить спички регулярных выражений внутри замены в 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>"; 
    }); 
}); 

alert() «s выход:

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

Update: упрощена структура и соответствие пример:

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

Вы можете не упрощать свой код, регулярное выражение, и разметку, чтобы люди могли более легко понять вашу проблему и, следовательно, поможет вам больше? (Не риторический вопрос) –

+0

Я добавил более простую версию, это имеет смысл? – travis

+0

Подожди, «ты не можешь ...» ты говорил, что я уже слишком упростил это? – travis

ответ

1

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

$(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() массива, insid e пользовательской функции .replace() просто не кажется очень экономичным. Это дает мне результат, который я искал.

4

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

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

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

Если да, то

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

Закрыть, я пытаюсь перебирать матчи определенной группы. так что для «abcdcdef» .match (/ ab (cd) + ef /) как мне перебирать несколько совпадений в $ 1? – travis

1

Хорошенькая петлю можно с помощью крюка схеме:

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