2013-03-19 1 views
0

У меня есть следующее регулярное выражение, где я пытаюсь захватить идентификаторы каждого комментария начала. Но по какой-то причине я могу только захватить первый. Он не получит идентификатор вложенного комментария. Он печатает только 1000 на консоль. Я пытаюсь заставить его захватить как 1000, так и 2000. Может ли кто-нибудь обнаружить ошибку в моем регулярном выражении?Regex для захвата идентификаторов из текста

<script type="text/javascript"> 

    function ExtractText() { 
     var regex = /\<!--Start([0-9]{4})-->([\s\S]*?)<!--End[0-9]{4}-->/gm; 
     var match; 
     while (match = regex.exec($("#myHtml").html())) { 
      console.log(match[1]); 
     } 
    } 

</script> 

<div id="myHtml"> 
    <!--Start1000-->Text on<!--Start2000-->the left<!--End1000-->Text on the right<!--End2000--> 
</div> 

На основании ответа Майк Самуила Я обновил мой JS к следующему:

function GetAllIds() { 

     var regex = /<!--Start([0-9]{4})-->([\s\S]*?)<!--End\1-->/g; 
     var text = $("#myHtml").html(); 
     var match; 
     while (regex.test(text)) { 
      text = text.replace(
       regex, 
       function (_, id, content) { 
        console.log(id); 
        return content; 
       }); 
     } 
    } 

ответ

2

В

<!--Start1000-->Text on<!--Start2000-->the left<!--End1000-->Text on the right<!--End2000--> 

"1000" область перекрывает "2000" область , но петля exec находит только неперекрывающийся матовый hes, так как каждый вызов exec с тем же регулярным выражением и строкой начинается в конце последнего совпадения. Чтобы решить эту проблему, попробуйте

var regex = /<!--Start([0-9]{4})-->([\s\S]*?)<!--End\1-->/g; 
for (var s = $("#myHtml").html(), sWithoutComment; 
    // Keep going until we fail to replace a comment bracketed chunk 
    // with the chunk minus comments. 
    true; 
    s = sWithoutComment) { 
    // Replace one group of non-overlapping comment pairs. 
    sWithoutComment = s.replace(
    regex, 
    function (_, id, content) { 
     console.log(id); 
     // Replace the whole thing with the body. 
     return content; 
    }); 
    if (s === sWithoutComment) { break; } 
} 
+0

+1 Я не поверил, пока я не попробовал это для себя, но это работает. –

+0

@ p.s.w.g, Да. Побочные эффекты в функциях replacer несколько неприятны, но есть всего несколько способов получить все совпадающие совпадения - итеративное совпадение и удаление старых совпадений; попробуйте сопоставить все суффиксы с регулярным выражением, привязанным к '^'; или попробуйте все префиксы с regex с конечным привязкой ('' ''). –

+0

Хм .. Кажется, печатать 1000 дважды вместо 1000 и 2000. Это близко, хотя! Я думаю, что есть две дополнительные круглые скобки на конце – TGH

1

Вы можете использовать группировку, а затем другой регулярное выражение:

var regex = /(<!--Start)([0-9]{4})/ig; 
var str = document.getElementById('myHtml').innerHTML; 
var matches = str.match(regex); 
for(var i=0;i<matches.length;i++){ 
    var m = matches[i]; 
    var num = m.match(/(\d+)/)[1]; 
    console.log(num); 
} 
Смежные вопросы