Java Regex Matcher Вопрос - PullRequest
       7

Java Regex Matcher Вопрос

0 голосов
/ 04 апреля 2010

Как мне сопоставить строку URL, например:

img src = "https://stackoverflow.com/a/b/c/d/someimage.jpg"

где фиксировано только имя домена и расширение файла (jpg), а другие переменные?

Следующий код не работает:

Pattern p = Pattern.compile("<img src=\"http://stachoverflow.com/.*jpg");
    // Create a matcher with an input string
    Matcher m = p.matcher(url);
    while (m.find()) {
     String s = m.toString();
    }

Ответы [ 2 ]

2 голосов
/ 04 апреля 2010

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

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TCPChat {

  static public void main(String[] args) {
    String url = "<img src=\"http://stackoverflow.com/a/b/c/d/someimage.jpg\">";
    Pattern p = Pattern.compile("<img src=\"http://stackoverflow.com/.*jpg\">");
    // Create a matcher with an input string
    Matcher m = p.matcher(url);
    while (m.find()) {
      String s = m.toString();
      System.out.println(s);
    }
  }
}
1 голос
/ 04 апреля 2010

Во-первых, я бы использовал метод group() для получения сопоставленного текста, а не toString(). Но, вероятно, вам нужна только часть URL, поэтому я бы использовал скобки для захвата этой части и вызова group(1) ее получения.

Во-вторых, я бы не предположил, что src был первым атрибутом в теге <img>. Например, в SO ему обычно предшествует атрибут class. Вы хотите добавить что-то, совпадающее с промежуточными атрибутами, но убедитесь, что оно не может совпадать после конца тега. [^<>]+ вероятно будет достаточно.

В-третьих, я бы использовал что-то более ограничительное, чем .*, чтобы сопоставить неизвестную часть с путем. Всегда есть вероятность, что вы найдете два URL в одной строке, например:

<img src="http://so.com/foo.jpg"> blah <img src="http://so.com/bar.jpg">

В этом случае .* в вашем регулярном выражении уменьшит разрыв, предоставив вам один матч там, где вы хотели два. Опять же, [^<>]*, вероятно, будет достаточно ограничительным.

Есть также несколько других потенциальных проблем. Значения атрибутов всегда заключены в двойные кавычки, или они могут быть заключены в одинарные кавычки или вообще не заключены в кавычки? Будут ли пробелы вокруг =? Имена элементов и атрибутов всегда строчные?

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

Вот моя пересмотренная версия вашего регулярного выражения (в виде строкового литерала Java):

"(?i)<img[^<>]+src\\s*=\\s*[\"']?(http://stackoverflow\\.com/[^<>]+\\.jpg)"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...