Cómo usar negación en Expresiones Regulares para omitir cadenas exactas dentro de un patrón

Estoy usando asp clásico en donde tengo una variable que contiene un código HTML tal que así:

<ul>
  <li><a href="http:\\salto1"><img src="imagen1.jpg" />Salto 1</a><li>
  <li><a href="http:\\salto2"><img src="imagen2.jpg" />Salto 2</a><li>
  <li><a href="http:\\salto3"><img src="imagen3.jpg" />Salto 3</a><li>
</ul>

Y estoy intentando por todos los medios mediante expresiones regulares tratar de reemplazar el href del enlace por el src de la imagen, pero no tengo forma alguna de conseguirlo.

Mi idea es, para que no coja un src que no le corresponda, encontrar la cadena que empiece en <a href y acabe en </a> siempre y cuando no haya ningún </a ya dentro en ella. De esta forma me aseguro que los posibles patrones que le ponga no coja más código del que deba.

El problema es que en expresiones regulares la negación debe ir dentro de corchetes, anulando en todo momento que sea una negación de una cadena exacta:

[^<\\a] --> Viene a ser sólo ver un carácter, que NO SEA "<", que NO SEA "\" o que NO SEA "a"

Estoy buscando posibles soluciones u otros enfoques.

5
задан 19.12.2016, 14:24
1 ответ

После того, как прежде всего, манипулировал бы HTML, ты был бы должен использовать программные средства, разработанные для этого. Правильный способ это делать - используя DOM. Изменение в коде HTML, даже, если он минимальный, способствовал бы тому, чтобы регулярное выражение не удалось. Я рекомендую тебе предотвращать использование regex для этого, и только он думал бы о том, чтобы использовать то, что я отвечаю внизу в случаях, в которых были бы полностью уверен, что HTML продолжает установленный формат, и он не изменится.


Проблема состоит в том, что в регулярных выражениях отрицание должно идти внутри квадратных скобок.

Это не правильно. Квадратные скобки используются, чтобы совпадать с классом символов (даже, когда она отрицалась одним ^), что совпадают с единственным характером.

Чтобы искать совпадения, которые не были бы продолжены главным файлом, используются отрицательные инспекции (negative lookaheads).
Синтаксис (?!patrón), что было бы возможно переводить, как "он не продолжен из-за". А именно, попробуй совпадать с главным файлом и, если он совпадает, настоящая попытка не удается. Эти инспекции не тратят символы, после будучи попробованы (он поворачивается в положение, в котором были перед инспекцией).


Моя идея, - для того, чтобы он не взял один src что ему не следовало, находить цепь, которая начинается в <a href и закончитесь в </a> всякий раз когда не было никакой </a уже внутри в ней. В этой форме я убеждаюсь, что возможные главные файлы, которые он помещает ему, он не взял больше код того, который должен.

RegEx:

(<a href\s*=\s*")[^"]*("[^<]*(?:<(?!\/a\b)[^<]*)*?<img\b[^>]*? src\s*=\s*"([^"]*)")

Замена:

$1$3$2

Описание:

  • (<a href\s*=\s*") - Группа 1 (он захватывает в $1)
    Совпади с буквальным текстом <a href=" (с опциональным местом около равного).

  • [^"]* - Любое количество символов, которые не были бы кавычками (контент href).

  • ("[^<]*(?:<(?!\/a\b)[^<]*)*?<img\b[^>]*? src\s*=\s*"([^"]*)") - Группа 2 (он захватывает в $2).

    • "[^<]* - кавычки, которые закрывают src следуемые любым количеством символов, которые не были бы <.

    • (?:<(?!\/a\b)[^<]*)*? - и необязательно (все те меньше было возможно) один <, каждый раз, когда он не был продолжен /a (здесь он, где мы используем negative lookahead), потом следуемый большим количеством символов, которых не было бы одним <.

    • <img\b[^>]*? - буквальный текст <img следуемый символами, которые не были бы > (мы остаемся внутри tag img).

    • src\s*=\s*" - буквальный текст src=" (с опциональным местом около равного).

    • ([^"]*) - Группа 3 (он захватывает в $3).
      Любое количество символов, которые не были бы кавычками (контент src).

    • " - кавычки, которые закрывают src.

Заменив из-за $1$3$2 мы заменяем из-за: начало этикетки a до кавычек, которые открываются href (1$) + контент src (3$) + оставшаяся часть, с кавычек, которые закрывают href в дальнейшем (2$).

Рассуждения:

Регулярное выражение было написано, чтобы выполнять случаи, показанные в вопросе. Хотя они покрывают правильно ожидаемый синтаксис, как комментировали, что сначала, всегда будут исключения, которые заставят ее не удаваться.
Между ними: если есть 2 изображения внутри той же этикетки a, только возьми первую, с которой он совпадает; если есть кавычки, убежавшие внутри какой-то унифицированный указатель ресурса (хотя не было бы должно быть), он берет их, как который он закрывается там; если есть какой-то параметр внутри этикетки img стоимость которого закончилась в src= он бы это взял ошибочно; они - какие-то из тех, которые приходят в голову мне, чтобы подтверждать примерами, но есть больше.

Код:

<%
Set regEx = New RegExp
regEx.Global = True
textoHTML = "<a href=""imagen1.jpg""><img src=""imagen1.jpg"" />Salto 1</a>"
regEx.Pattern = "(<a href\s*=\s*"")[^""]*(""[^<]*(?:<(?!\/a\b)[^<]*)*?<img\b[^>]*? src\s*=\s*""([^""]*)"")"
reemplazo = "$1$3$2"
Response.Write regEx.Replace( textoHTML, reemplazo)
%>

Результат:

<a href="imagen1.jpg"><img src="imagen1.jpg" />Salto 1</a>

Demo:

https://www.myregextester.com/? r=bf0a0b25

6
ответ дан 24.11.2019, 12:01
  • 1
    Это " negative lookaheads" desconocí в полностью. Если не конечно это дорожка, чтобы бросать. 10! – Andynedine 19.12.2016, 14:05
  • 2
    Muchí пропасти спасибо за открытие мне стольких окон :D. Это манипулирования DOM serí в гениальный. Просматривая уже основательно есть librerí схвати изюм vbscript, которым позволяют манипулировать XML, просвет... :) Мы попробуем видеть эту opció n tambié n. – Andynedine 19.12.2016, 14:11
  • 3
    Я верю в то, что có mo использовать DOM serí в новый вопрос, и есть различные формы (и я не помню cuá l serí в má s prá ctica сегодня в dí в в ASP). Пример podrí чтобы быть Parsing XML with ASP – Mariano 19.12.2016, 14:12
  • 4
    Здравствуйте. Если он чем-то служит, всегда использовал regexr и debuggex , чтобы отображать и тестировать регулярные выражения. – UselesssCat 20.12.2016, 23:51
  • 5
    @ArieCwHat ни одна из этих не использует механизм, который использует ASP... Podrá s находить má s программные средства в descripció n этикетки regex – Mariano 20.12.2016, 23:52