Повторные группы регулярных выражений - PullRequest
1 голос
/ 19 июня 2009

У меня есть такой шаблон, который соответствует нескольким наборам значений:

(((\w+) (\d+))+)

Я думаю, что это будет соответствовать:

one 1 two 2 three 3 four 4 five 5

Но поскольку я не знаю, сколько их повторений, я не знаю, что добавить в вывод.

Например, мне нужно получить результаты примерно так:

<span class="one">1</span>
<span class="two">2</span>
<span class="three">3</span>
<span class="four">4</span>
<span class="five">5</span>

Так что-то вроде этого:

/(((\w+) (\d+))+)/ig, "<span class=\"$3\">$4</span>"

Не будет работать, потому что мне нужно создать переменное количество элементов span.

Есть ли что-то, что я здесь упускаю?

Спасибо!

Ответы [ 6 ]

3 голосов
/ 19 июня 2009

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

  • /(\w+) (\d+)/ соответствует "five 5" или "one 1", но не "one 1two 2"
  • /(?:(\w+) (\d+))+/ соответствует "one 1" или "one 1two 2" или "one 1two 2three 3" и т. Д.

+ соответствует предыдущему шаблону 1 или более раз.

(Примечание: (?:...) похоже на (...), за исключением того, что оно ничего не фиксирует в $1, $2 и т. Д., Оно просто группирует вещи)

Так что для вашей проблемы, вам просто нужно сбросить +:

/(\w+) (\d+)/ig, "<span class=\"$1\">$2</span>"

Флаг /g (global) позаботится о повторении вашей замены при каждом совпадении шаблона.

2 голосов
/ 19 июня 2009

Вместо того, чтобы пытаться повторить совпадения, просто используйте (\w+) (\d+) и повторите замену несколько раз (что и делает флаг глобальной замены g).

Примечание: имеющийся у вас флаг i является избыточным, поскольку \ w включает оба регистра, а \ d является только числовым.

При условии, что все остальные части страницы настроены надлежащим образом, а $ j является объектом jQuery, это будет работать по желанию:

var MyText = $j(something).text();

HtmlContent = MyText.replace( /(\w+) (\d+)/g , '<span class="$1">$2</span>' );

$j(something).html( HtmlContent );
2 голосов
/ 19 июня 2009

Я думаю, вы просто захотите разделить на пробелы в этом случае:

s = "one 1 two 2 three 3 four 4 five 5";

// Replace runs of whitespace with a single space, and trim...
s.replace(/\s+/g, ' ');
s.replace(/^\s+|\s+$/g, '')

// And split string into an array
var parts = "one 1 two 2 three 3 four 4 five 5".split(' ')

for (var i=0; i<parts.length; i++){

    // Get your pieces
    var name = parts.shift();
    var num = parseInt(parts.shift());

    // Create your span
    var span = $('<span></span>').attr('class', name).text(num);

}
0 голосов
/ 19 июня 2009

Почему бы вам не иметь их в массиве, что имеет больше смысла (если вы на самом деле делаете связки с числами):

var arr = ['one','two','three','four','five','six','seven','eight','nine','ten'];

$.each(arr, function(i, val) {
   var $span = $('<span></span>').attr('class', val).text(i+1);
   $('#someDiv').append($span);
});
0 голосов
/ 19 июня 2009

Следующие работы в VIM.

:%s/\(\w\+\) \(\d\+\)/<span class="\1">\2<\/span>\r/ig

Подобное должно работать в jquery.

0 голосов
/ 19 июня 2009

Ваш вопрос не дает ответа? Я только что тестировал с консолью javascript:

>>> "one 1 two 2 three 3 four 4 five 5".replace(/(((\w+) (\d+))+)/ig, "<span class=\"$3\">$4</span>")
<span class="one">1</span> <span class="two">2</span> <span class="three">3</span> <span class="four">4</span> <span class="five">5</span>

>>> "one 1 two 2 three 3 four 4".replace(/(((\w+) (\d+))+)/ig, "<span class=\"$3\">$4</span>" )
<span class="one">1</span> <span class="two">2</span> <span class="three">3</span> <span class="four">4</span>

>>> "one 1 two 2 three 3".replace(/(((\w+) (\d+))+)/ig, "<span class=\"$3\">$4</span>" )
<span class="one">1</span> <span class="two">2</span> <span class="three">3</span>

>>> "one 1 two 2 three 3 foo five 5".replace(/(((\w+) (\d+))+)/ig, "<span class=\"$3\">$4</span>" )
<span class="one">1</span> <span class="two">2</span> <span class="three">3</span> foo <span class="five">5</span>

Кажется, это именно то, что вы хотите.

Редактировать: оригинальный ответ ниже; Я пропустил тег jquery, подумал, что это вопрос регулярного выражения ...

Не пытайтесь сопоставить их все сразу; пусть / g справится с этим ...

bash$ echo "one 1 two 2 three 3 four 4 five 5" | \
      sed -e 's/\([[:alpha:]]\+\)\s*\([[:digit:]]\+\)\s*/<span class="\1">\2<\/span>\n/g'

, что дает

<span class="one">1</span>
<span class="two">2</span>
<span class="three">3</span>
<span class="four">4</span>
<span class="five">5</span>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...