Допускается ли ">" (U + 003E БОЛЬШЕ, ЧЕМ ЗНАК) внутри значения атрибута html-element?

Другими словами, можно ли использовать регулярное выражение /<tag[^>]*>.*?</tag>/ для соответствия HTML-элементу tag, который не содержит вложенных элементов tag?

Например (lt.html):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>greater than sign in attribute value</title>
  </head>
  <body>
    <div>1</div>
    <div title = ">">2</div>
  </body>
</html>

Регулярное выражение:

$ perl -nE"say  if m~<div[^>]*>(.*?)</div>~" lt.html

И экран-скребок:

#!/usr/bin/env python
import sys
import BeautifulSoup

soup = BeautifulSoup.BeautifulSoup(sys.stdin)
for div in soup.findAll('div'):
    print div.string


$ python lt.py <lt.html

Оба дают одинаковый результат:

1
">2

Ожидаемый результат:

1
2

w3c говорит:

Attribute values are a mixture of text and character references, except with the additional restriction that the text cannot contain an ambiguous ampersand.

Это пример из учебника, который все используют, чтобы объяснить, почему вы не должны использовать регулярные выражения для синтаксического анализа HTML, вам следует использовать HTML Parser.

AmbroseChapel 25.09.2008 05:47
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
10
1
3 512
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

yeah except /<tag[^>]*>.*?</tag>/

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

Я не понимаю. Не могли бы вы привести пример?

jfs 18.09.2008 21:31

@ j-f-sebastian: <div class = 'foo'> <span> flo </span> <div> bar </div> </div> вы соответствуете первому <div, но также и первому </ div

PhiLho 16.09.2009 16:02

посмотрите, получите ли вы тот же результат, используя & gt; вместо>

Прочитав следующее:

http://www.w3.org/International/questions/qa-escapes

похоже, что экраны сущностей предлагаются везде (в том числе в атрибутах) для <> и &

Этот документ неверен. Знаки "больше чем" в содержании действительны. Он также говорит, что одиночные амперсанды неверны, но это не всегда так для HTML.

Jim 18.09.2008 21:23

Он не говорит, что знаки «больше» недействительны, он просто рекомендует вместо этого использовать сущности - рекомендация, которую проигнорирует только дурак, ИМО. Кого волнует, действительно ли это, если большинство программистов, включая авторов многих программных инструментов, считают, что это не так?

Alan Moore 29.04.2009 15:40

Я считаю, что это действительно так, и валидатор W3C соглашается, но авторитетным источником этой информации является стандарт ISO 8879: 1986, который стоит ~ 150 евро / 210 долларов США. Тем не менее, их кодирование не является неправильным, поэтому, если сомневаетесь, кодируйте. Кроме того, если вы используете тип документа на основе XML, вам необходимо закодировать знаки «больше» в последовательности ]]>.

Литерал > разрешен везде в HTML-содержимом, как внутри значений атрибутов, так и в виде текста внутри элемента.

Если вы настаиваете на использовании регулярных выражений (что подходит для основных строковых операций), попробуйте использовать <tag((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)>.*?</tag>. Он должен идеально соответствовать атрибутам и, следовательно, позволять вам получить доступ к внутреннему содержимому (хотя вам нужно поместить его в группу захвата).

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

Ответ принят как подходящий

Да, это разрешено (W3C Validator принимает это, только выдает предупреждение).

Неэкранированные < и > также разрешены внутри комментариев, так что такое простое регулярное выражение можно обмануть.

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

Другие вопросы по теме