Ссылки на вложенные группы в JavaScript с использованием замены строк с использованием регулярных выражений - PullRequest
3 голосов
/ 06 мая 2011

Из-за того, как jQuery работает с тегами скрипта, я счел необходимым выполнить некоторые манипуляции с HTML с помощью регулярных выражений (да, я знаю ... не идеальный инструмент для работы).К сожалению, мне кажется, что мое понимание того, как работают захваченные группы в JavaScript, неверно, потому что, когда я пытаюсь это сделать:

var scriptTagFormat = /<script .*?(src="(.*?)")?.*?>(.*?)<\/script>/ig;

html = html.replace(
    scriptTagFormat, 
    '<span class="script-placeholder" style="display:none;" title="$2">$3</span>');

Теги сценария заменяются интервалами, но полученный атрибут title остается пустым,Разве $2 не должен соответствовать содержимому атрибута src тега сценария?

Ответы [ 5 ]

4 голосов
/ 06 мая 2011

Вложение групп не имеет значения;их нумерация определяется строго позициями открывающих скобок в регулярном выражении.В вашем случае это означает, что это группа № 1, которая захватывает всю последовательность src="value", и группа № 2, которая захватывает только часть value.

1 голос
/ 06 мая 2011

Попробуйте это:

/<script (?:(?!src).)*(?:src="(.*?)")?.*?>(.*?)<\/script>/ig

Смотрите здесь: Рубуляр

Как писал Stema, .*? слишком много соответствует. С отрицательным прогнозом (?:(?!src).)* вы будете соответствовать только до атрибута src.

Но на самом деле в этом случае вы также можете просто переместить .*? в необязательную часть:

/<script (?:.*?src="(.*?)")?.*?>(.*?)<\/script>/ig

Смотри здесь: Рубуляр

1 голос
/ 06 мая 2011

.*? слишком много соответствует, потому что следующая группа является необязательной, ==> ваш src соответствует одному из .*? вокруг. если вы удалите ? после первой группы, это сработает.

Обновление: как указывал @morja, ваше решение - переместить первый .*? в необязательную часть src.

Просто для полноты: /<script (?:.*?(src="(.*?)"))?.*?>(.*?)<\/script>/ig

Вы можете увидеть это здесь, на рубрике (исправил и мою ссылку)

Если вы не хотите использовать содержимое первой группы захвата, то сделайте ее группой без захвата, используя (?:)

/<script (?:.*?(?:src="(.*?)"))?.*?>(.*?)<\/script>/ig

Тогда ваш желаемый результат в $ 1 и $ 2.

0 голосов
/ 06 мая 2011

Я думаю, что регулярные выражения сами по себе не могут сделать именно то, что я ищу, поэтому вот моя модификация, чтобы обойти проблему:

var scriptTagFormat = /<script\s+((.*?)="(.*?)")*\s*>(.*?)<\/script>/ig;

html = html.replace(
    scriptTagFormat, 
    '<span class="script-placeholder" style="display:none;" $1>$4</span>');

Раньше я хотел избежать установки нестандартных атрибутов на замену span. Этот код слепо копирует все атрибуты. К счастью, нестандартные атрибуты не удаляются из DOM, когда я вставляю HTML, поэтому он будет работать для моих целей.

0 голосов
/ 06 мая 2011

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

Мое первое предположение состоит в том, что один из ваших тегов сценария не имеет src, что означает, что вы остались с одной группой захвата (содержимым сценария).

...