Разбор css фонового URL-адреса и селектора с использованием регулярного выражения - PullRequest
0 голосов
/ 08 июля 2020

Я пытаюсь изменить страницу HTML со встроенными стилями, я хочу создать выражение регулярного выражения, которое фиксирует фоновый URL-адрес и селектор, например:

<div>some html here</div>
<style>#some-selector {
  padding-top: 408px;
}
#some-selector .bg {
  background-image: url(www.some-url.com/some-image.jpg);
}
#some-selector {
  background-position: 43% 97%;
}

то, что я хочу захватить вот #some-selector .bg и www.some-url.com/some-image.jpg, имейте в виду, что страница HTML большая, и выражение должно быть быстрым

Я придумал это выражение <style[\s\S]*?[>}\/\n](.*){[\s\S]*?background.*?url\((.*?)\), но оно работает неправильно, я знаю, что я первый [\s\S] должен быть жадным, но когда я удаляю ?, это приводит к катастрофе c откат <style[\s\S]*[>}\/\n](.*){[\s\S]*?background.*?url\((.*?)\) он работает с небольшими строками, но на всей странице он вызывает катастрофический c откат, я Я использовал regex101 для проверки.

Любая помощь приветствуется

Изменить: вот пример https://regex101.com/r/ZMxOSz/1

1 Ответ

0 голосов
/ 09 июля 2020

обновить После более внимательного рассмотрения я предлагаю 2 решения, которые в относительной степени смягчают проблему обратного отслеживания. Прежде чем рассматривать их, я хочу указать на то, что с синтаксисом CSS связано очень мало разделителей. Более того, это больше связано с порядком и содержанием разрешенных символов, которые определяют синтаксис CSS.

Лекарство от поиска с возвратом состоит в том, чтобы ограничить механизм регулярных выражений меньшим количеством допустимых символы для соответствия и в пределах стратегии c позиции. Если вы посмотрите здесь спецификацию CSS -> https://www.w3.org/TR/CSS21/syndata.html вы заметите, что он полностью определяется регулярными выражениями. Это указывает на то, что парсеры CSS полностью построены с использованием обрезанной версии регулярного выражения.

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

Вместо этого я предлагаю эти 2 регулярных выражения, адаптированные к вашему запросу.

Первое:

  • Соответствует только первому url() блоку в элементе <style>

<style[^>]*?>(?:[^{}:]*{[^{}]*?:[^{}()]*?})*?(?:([^{}:]*){[^{}]*?:\s*url\s*\(\s*([^{}()]*?)\s*\)\s*})

см. -> https://regex101.com/r/2SNIks/1

Второй:

  • Соответствует всем блокам url() с элементом <style>

(?:<style[^>]*?>|(?!^)\G)(?:(?:(?!</style)[^{}:])*{[^{}]*?:[^{}()]*?})*?(?:([^{}:]*){[^{}]*?:\s*url\s*\(\s*([^{}()]*?)\s*\)\s*})

см. -> https://regex101.com/r/d8q6LH/1

Для обоих регулярных выражений

  • Селектор находится в группе 1
  • URL-адрес находится в группе 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...