Вопрос по java, regex – Регулярное выражение для получения атрибута из тега HTML

14

Я ищу регулярное выражение, которое может получить тег src (без учета регистра) из следующих фрагментов HTML в Java.

<html><img src="kk.gif" alt="text"/></html>
<html><img src='kk.gif' alt="text"/></html>
<html><img src = "kk.gif" alt="text"/></html>

Ваш Ответ

4   ответа
17

Этот вопрос часто возникает здесь.

Регулярные выражения являютсяbad способ решения этой проблемы. Сделайте себе одолжение и используйте какой-нибудь HTML-парсер.

Регулярные выражения некорректны при разборе HTML. В конечном итоге вы получите сложное выражение, которое в некоторых угловых случаях будет вести себя неожиданно.will случилось иначе.

Edit: If тогда ваш HTML так прост:

Pattern p = Pattern.compile("src\\s*=\\s*([\\"'])?([^ \\"']*)");
Matcher m = p.matcher(str);
if (m.find()) {
  String src = m.group(2);
}

И здесьлюбое количество парсеров Java HTML там

Сказать, что без ссылки на парсер не очень полезно.
Согласен; но у меня есть небольшой фрагмент данных и для каждого элемента данных в цикле, и я не уверен, будет ли загрузка и получение значения парсером жизнеспособной с точки зрения производительности Krishna Kumar
@wds, говоряthat без ссылки на парсер тоже не полезно;). Вот список Java-парсеров с открытым исходным кодом:java-source.net/open-source/html-parsers
даже xpath будет лучше для этогоsigh
@cletus, только к вашему сведению - яwas использование анализатора HTML, потому что теоретический, «сделай что-нибудь» - «Правильный путь (tm)» часть меня хотела, ну, делать все правильно. :) К сожалению, оказывается, что запускать анализатор HTML - даже легкий - - на десятках строк HTML на устройствах с ограниченными ресурсами Android было признано немного непрактичным. С другой стороны, метод регулярных выражений чрезвычайно быстр ... время обработки было сокращено с ~ 30 секунд на канал RSS (в среднем 10 строк HTML для анализа на канал) до ~ 2 секунд. Обход синтаксического анализатора с использованием базового решения XPath может быть хорошим компромиссом.
24

Одна возможность:

String imgRegex = "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";

это возможность (если сопоставляется без учета регистра). Это немного беспорядок и намеренно игнорирует случай, когда кавычки не используются. Чтобы представить его, не беспокоясь о экранировании строк:

<img[^>]+src\s*=\s*['"]([^'"]+)['"][^>]*>

Это соответствует:

  • <img
  • one or more characters that aren't > (i.e. possible other attributes)
  • src
  • optional whitespace
  • =
  • optional whitespace
  • starting delimiter of ' or "
  • image source (which may not include a single or double quote)
  • ending delimiter
  • although the expression can stop here, I then added:
    • zero or more characters that are not > (more possible attributes)
    • > to close the tag

Things to note:

  • If you want to include the src= as well, move the open bracket further left :-)
  • This does not care about delimiter balancing or attribute values without delimiters, and it can also choke on badly-formed attributes (such as attributes that include > or image sources that include ' or ").
  • Parsing HTML with regular expressions like this is non-trivial, and at best a quick hack that works in the majority of cases.
Первое совпадение должно вернуть то, что вы хотите. Увидетьjava.sun.com/docs/books/tutorial/essential/regex/groups.html как получить доступ к группе. Вы по сути хотите использоватьgroup() метод вашего результата совпадения с аргументом1.
Спасибо; это возвращает "& lt; img src =" kk.t "& gt;" сопоставить со строкой & lt; html & lt; img src = "kk.t" & gt; / html & gt ;. может ли это выражение быть изменено, чтобы получить меня только "kk.txt"; надеюсь, я не прошу слишком много;) Krishna Kumar
Я также хочу получить полный & lt; a & gt; / lt; / a & gt; как это сделать?
Я так рад, что в этом мире есть люди, которые не только понимают регулярные выражения гораздо больше, чем я, но и достаточно хороши, чтобы поделиться этим пониманием. Это регулярное выражение было именно то, что мне нужно. Спасибо!!!
Посмотрите код из вышеупомянутого кода для примера того, как получить захваченную подгруппу - вы просто хотите, чтобы аргументgroup() быть1.
0

Вы имеете в виду src-атрибут img-Tag? В этом случае вы можете пойти со следующим:

<[Ii][Mm][Gg]\\s*([Ss][Rr][Cc]\\s*=\\s*[\"'].*?[\"'])

Это должно работать. Выражение src = "..." находится в параграфах, так что это группа соответствия и может обрабатываться отдельно.

Я исправил некоторые проблемы.
Я снова отредактировал, чтобы включить одинарные кавычки.
Это будет работать до тех пор, пока кто-нибудь не использует апострофы вместо двойных кавычек для ограничения значения атрибута (src = "foo"). Кроме того, ваш подход потерпит неудачу, если у тега img будут другие атрибуты. Сложность довольно высока, хотя в большинстве случаев вы можете получить правильное выражение. У меня нет одной под рукой, хотя.
да; Мне нужен атрибут src с картинки; но это компиляция выражений в Java; Можете ли вы подтвердить это? Krishna Kumar
Спасибо за ответ; эта компиляция regEx терпит неудачу в Java с следующей ошибкой. java.util.regex.PatternSyntaxException: незакрытая группа рядом с индексом 43 & lt; [Ii] [Mm] [Gg] \ s * ([Ss] [Rr] [Cc] \ s * = \ s * \ & quot;. * ? \ & quot; ^ Krishna Kumar
1

Этот ответ для поисковиков Google, потому что слишком поздно

Копирование клитов показало ошибку и Изменение его ответа и передача измененной строкиsrc\\s*=\\s*([\"'])?([^\"']*) как параметр передается вPattern.compile работал на меня,

Вот полный пример

    String htmlString = "<div class=\"current\"><img src=\"img/HomePageImages/Paris.jpg\"></div>"; //Sample HTML

    String ptr= "src\\s*=\\s*([\"'])?([^\"']*)";
    Pattern p = Pattern.compile(ptr);
    Matcher m = p.matcher(htmlString);
    if (m.find()) {
        String src = m.group(2); //Result
    }

Похожие вопросы