">" (U + 003E GREATER-THAN SIGN) допускается внутри значения атрибута html-элемента? - PullRequest
8 голосов
/ 18 сентября 2008

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

Regex:

$ perl -nE"say $1 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 говорит:

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

Ответы [ 7 ]

9 голосов
/ 20 октября 2008

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

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

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

3 голосов
/ 18 сентября 2008

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

3 голосов
/ 18 сентября 2008

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

2 голосов
/ 25 сентября 2008

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

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

2 голосов
/ 18 сентября 2008

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

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

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

0 голосов
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008
yeah except /<tag[^>]*>.*?<\/tag>/

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...