Другое

Регулярные выражения для HTML-тегов: Полное руководство

Узнайте, как создавать шаблоны регулярных выражений для сопоставления открывающих HTML-тегов, исключая самозакрывающиеся XHTML-теги. Полное руководство с примерами и лучшими практиками для веб-разработки.

Регулярное выражение для сопоставления открывающих HTML-тегов, но исключающее самозакрывающиеся XHTML-теги

Мне нужно создать регулярное выражение, которое сопоставляет все открывающие HTML-теги, такие как:

Но не должно сопоставлять самозакрывающиеся теги, такие как:


Я придумал следующий шаблон регулярного выражения:
<([a-z]+) [^/]?>

Может кто-нибудь проверить, правильно ли этот шаблон сопоставляет открывающие HTML-теги, исключая самозакрывающиеся? В частности, я хочу подтвердить, что:

  1. Он находит символ меньше (<)
  2. Захватывает одну или более строчных букв (a-z)
  3. Разрешает ноль или более пробелов
  4. Сопоставляет любой символ ноль или более раз (жадно), за исключением прямого слэша (/)
  5. Заканчивается символом больше (>)

Правильно ли я понимаю это регулярное выражение? И что более важно, решает ли этот шаблон проблему сопоставления открывающих HTML-тегов при исключении самозакрывающихся XHTML-тегов?

Анализ регулярного выражения для HTML-тегов

Ваше регулярное выражение <([a-z]+) *[^/]*?> является хорошей отправной точкой для сопоставления открывающих HTML-тегов с исключением самозакрывающихся XHTML-тегов, но у него есть некоторые ограничения и потенциальные граничные случаи, которые следует учитывать.

Разбор вашего анализа:

  1. Символ “меньше” (<) - ✓ Правильно соответствует открывающей угловой скобке
  2. Захват строчных букв (([a-z]+)) - ✓ Правильно захватывает имя тега
  3. Ноль или более пробелов ( *) - ✓ Разрешает необязательные пробельные символы
  4. Символы, не являющиеся косой чертой ([^/]*) - ✓ Это ключевой механизм исключения
  5. Нетерпеливый символ “больше” (?>) - ✓ Находит первый > в строке

Содержание

Анализ регулярного выражения

Ваш шаблон работает, гарантируя, что перед закрывающим > не появляется косая черта (/). Это эффективно исключает самозакрывающиеся XHTML-теги, такие как <br /> и <hr class="foo" />, поскольку они содержат / перед конечным >.

Как он соответствует открывающим тегам:

  • <p> - находит <p> без / перед >
  • <a href="foo"> - находит <a href="foo"> без / перед >

Как он исключает самозакрывающиеся теги:

  • <br /> - мог бы соответствовать <br > (перед /), но [^/]* предотвращает соответствие любому /, поэтому он правильно исключает полный тег ✓
  • <hr class="foo" /> - применяется та же логика ✓

Сильные стороны шаблона

  • Простой и читаемый - Легко понять и поддерживать
  • Хорошая производительность - Минимальный возврат из-за механизма исключения [^/]>
  • Захватывает имена тегов - Группа ([a-z]+) дает доступ к имени тега
  • Обрабатывает атрибуты - Работает с тегами, имеющими атрибуты
  • Теги без учета регистра - Фокусируется на строчных буквах, что является стандартом

Потенциальные ограничения

  1. Синтаксис самозакрытия в HTML5 - HTML5 разрешает <tag/> без пробела перед /
  2. Теги с разным регистром - Не обрабатывает заглавные буквы в именах тегов
  3. HTML-комментарии - Может потенциально соответствовать внутри комментариев
  4. Содержимое script/style - Может соответствовать тегам внутри блоков <script> или <style>

Улучшенные альтернативы

Для более надежного разбора HTML рассмотрите эти альтернативы:

regex
<([a-z][a-z0-9]*)\b[^>]*>(?!/)

Эта версия:

  • Использует \b границу слова для лучшего соответствия имени тега
  • Добавляет [a-z0-9]* для обработки цифр в именах тегов
  • Включает (?!/) негативную проверку вперёд для гарантии отсутствия /

Для соответствия без учета регистра:

regex
<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(?!/)

Практические примеры

Ваш шаблон работает для:

  • <div>
  • <span class="highlight">
  • <a href="https://example.com">
  • <img src="photo.jpg" alt="description">

Ваш шаблон исключает:

  • <br />
  • <hr class="foo" />
  • <img src="photo.jpg" />

Граничные случаи

Потенциальные ложные срабатывания:

  • <tag/attribute="value"> - может некорректно соответствовать, если / появляется в значениях атрибутов

Потенциальные пропуски:

  • <TAG> - не будет соответствовать тегам в верхнем регистре
  • <br/> - отсутствие пробела перед / может быть пропущено в некоторых реализациях

Рекомендации

Ваше регулярное выражение функционально правильно для заявленных требований, но для производственного использования:

  1. Рассмотрите возможность использования парсера HTML такого как DOMDocument в PHP или BeautifulSoup в Python для более надежного разбора

  2. Если вы придерживаетесь регулярных выражений, улучшите его до:

regex
<([a-z][a-z0-9]*)\b[^>]*>(?![/>])
  1. Для соответствия без учета регистра, добавьте флаг i или используйте:
regex
<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(?![/>])
  1. Помните, что разбор HTML с помощью регулярных выражений имеет inherent ограничения - сложные HTML-структуры и граничные случаи могут все еще вызывать проблемы

Ваше понимание компонентов регулярного выражения правильное, и шаблон эффективно решает основную проблему различия открывающих HTML-тегов и самозакрывающихся XHTML-тегов в большинстве распространенных сценариев.

Источники

  1. Regular Expressions - MDN Web Docs
  2. HTML Parsing - W3C Specification
  3. Regex for HTML Tags - Stack Overflow
Авторы
Проверено модерацией
Модерация