2013-07-07 14 views
1

Я знаю, что это задавали миллион раз, прежде чем так обьяснялись для повторного вопроса, но это сводит меня с ума. Я работаю над этим целую вечность и, похоже, никуда не денутся.Обнаружение первого появления шаблона в регулярном выражении

У меня есть код html, содержащий изображения, перемещаемые вправо или влево. Мне нужно найти все плавающие изображения, удалить float и затем обернуть их в div, который теперь плавает так же, как и изображение.

например. от

<img src="images/imagepath1.jpg" border="0" alt="image 1" width="200" height="206" style="float: right;" />

в

<div class="imgContainer" style="float: right;"><img src="images/imagepath1.jpg" border="0" alt="image 1" width="200" height="206" /></div>

Я использую этот код в Notepad ++ Найти

<img src="(.+)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

Заменить

<div class="imgContainer" style="float: \6;"><img src="\1" border="\2" alt="\3" width="\4" height="\5" /></div>

Проблема заключается в том, что в блоке кода, содержащего <p> теги и несколько изображений, которые я выделить весь блок кода от начала до конца.

E.g.

<img src="images/imagepath1.gif" border="0" alt="image 1" width="207" height="119" style="float: right;" /><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</p> <img src="images/imagepath2.jpg" border="0" alt="image2" width="96" height="141" style="float: left;" /><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><img src="images/imagepath3.gif" border="0" alt="image 3" width="72" height="108" style="float: right;" />

В Notepad ++ это соответствует целый блок. Можете ли вы предложить какие-либо предложения, что он меня заводит!

Адам

ответ

1

Форвард

Убедитесь, что вы используете последнюю версию Notepad ++, там, где известные проблемы с использованием регулярных выражений в Блокноте ++ v5 и перед которой были исправлены в v6.

Basic

Хотя есть тонна крайних случаев, когда регулярное выражение имеет трудности обработки HTML, такие как:

  • атрибуты могут появляться в любом порядке в теге
  • значение атрибутов могут выглядеть фактические атрибуты, такие как <img onmouseover=' src="TheseAreNotTheDroidsYouAreLookingFor.png" ; funImageSwap(src); ' src="DecoyDroids.png">
  • значения атрибутов могут использовать одиночные двойные или не котировки

В своем выражении подумайте об изменении .+ на [^"]+. Это предотвратит регулярное выражение двигателя покинуть цитируемую область или тег и путешествие в следующий возможный матч

<img src="([^"]+)" border="([0-9]{1})" alt="([^"]*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" /> 

Но это не обрабатывает другие случаи краев.

комплекс

Чтобы обойти эти крайние случаи, вы могли бы использовать это выражение монстра. Я имею это на нескольких строках и прокомментировал здесь, чтобы показать, что происходит, чтобы облегчить понимание. однако в блокноте вам нужно будет удалить комментарии и все новые строки.

Regex

<img(?=\s|>) 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\ssrc=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find src, capture value including quotes if they exist 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find border, capture value including quotes if they exist 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find alt, capture value including quotes if they exist 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find width, capture value including quotes if they exist 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find height, capture value including quotes if they exist 
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left))) # find style, capture value including quotes if they exist 
[^>]*>      # actually capture the string 

Заменить

<div class="imgContainer" style="$6;"><img src=$1 border=$2 alt=$3 width=$4 height=$5 /></div> 

Это единственное выражение строки вставляется в мой блокноте пример. Я использую Notepad ++ v6.3.3

<img(?=\s|>)(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\ssrc=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left)))[^>]*>

enter image description here

Expanded

  • <img матча изображения тег
  • (?=\s|>) смотреть вперед, чтобы обеспечить имя изображений тега сопровождается пространственный или закрытый угловой кронштейн
  • (?= Посмотрите вперед, этот конкретный находит атрибут src, но идея одинакова для всех остальных. Взгляд вперед позволяет атрибутам появляться в любом порядке внутри тега, потому что после того, как взгляд вперед выполняется, двигатель регулярных выражений возвращается к тому, где начался просмотр и продолжается с остальной частью выражения.
    • (?: группа не захвата перемещает курсор регулярного выражения через строку, пропуская все значения атрибутов. Это волшебство, которое обходит значения атрибутов, которые могут быть ошибочно приняты как желаемое имя атрибута.
    • [^>=] матч все символы, которые не являются близкими скобки или знаки равенства
    • | или
    • ='[^']*' матч знаком равенства следуют одинарные кавычки, весь текст в одинарные кавычки и близко апостроф
    • | или
    • ="[^"]*" соответствует знаку равенства, за которым следуют двойные кавычки, весь текст внутри двойных кавычек и закрытая двойная кавычка
    • | или
    • =[^'"][^\s>]* знаком равенства следует, не кавычка, за которым следует любое количество символов, которые не являются пробелы или близкие угловые скобки
    • )*? закрывают вне группы захвата, и позволяет ей повторить столько раз, сколько необходимо. Захват не оставит метку так, если следующее условие не выполнено, то этот конкретный тег не тег, мы ищем
  • \ssrc= матча пространством с последующим src=.Благодаря вышеуказанной группе без захвата это может быть только имя атрибута
  • ( начало захвата группы это будет получить значение атрибута SRC
    • '[^']*' матч знаком равенства следуют одинарные кавычки, весь текст внутри одиночные кавычки и близко апостроф
    • | или
    • "[^"]*" матч знаком равенства следуют двойные кавычки, весь текст в двойных кавычках и закрыть двойные кавычки
    • | или
    • [^'"][^\s>]* знаком равенства следует, не кавычка которой следует любое количество символов, которые не являются пробелы или близкие угловые скобки
    • ) закрыть захвата группу
  • ) закрыть LOOKAHEAD
  • Эти следующие взгляды следуют той же логике, что и выше. Src
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*)) найти границу, значение захвата, включая кавычки, если они существуют
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*)) находка альт, значение захвата, включая кавычки, если они существуют
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*)) ширины найти, значение захвата, включая кавычки, если они существуют
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*)) высоты найти, значение захвата, включая кавычки, если они существуют
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left))) стиля найти, захват значение этого немного отличается из-за того, как сопоставляется фактическое значение атрибута
  • [^>]*> соответствует остальной части тега img и закрывающей скобки, что предотвращает использование регулярного выражения от acc acc идентично найти включенный атрибут, который может иметь значение, которое можно было бы принять за другой тег img.
+0

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

+0

Несомненно.См. Обновленный ответ :) –

+1

, что является огромным спасибо мужчине. Как я могу купить вам пиво? –

1

Я бы сказал, что вы на правильном пути, на расстоянии всего одного символа от поиска/замены регулярных выражений, которые вы придумали.

Это текущая находка:

<img src="(.+)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

Изменить это:

   v 

<img src="(.+?)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

The v показывает, где я представил 1 символ, который вы в данный момент отсутствует. Как только вы сделаете это .+ ленивым, вы сможете получить правильные замены, а не одну замену для всего.

В этом случае я также посоветую использовать [^"] вместо ..

+0

Ницца, спасибо, Джерри. Работал отлично, но у меня был крайний случай в каком-то другом коде и выбил его. Если бы изображение было поплыто, это не сработало бы. –

+0

@AdamSinnott Какие края вы считаете своими? img без каких-либо параметров (например, отсутствие ширины и высоты или какой-либо другой параметр)? Используя двойные/одинарные кавычки или нет? Я мог бы изменить регулярное выражение, чтобы включить кромки, которые, по вашему мнению, вы можете получить, как только подтвердите это. Если это только двойные/одинарные кавычки или нет, я думаю, вы можете использовать гораздо более короткое регулярное выражение и в то же время сделать параметры необязательными (например, если высота отсутствует, то у вас будет 'height =" "' в новом теге img). – Jerry

Смежные вопросы