Есть вариант использования, когда у меня есть длинное String, которое может содержать много <img> тегов.
Мне нужно собрать весь тег изображения от начала (<img src = ") до закрытия (">) в списке.
Я написал регулярное выражение ("<img.*?\">"gm) для их выбора, но не знаю, как собрать их все в список.
например:
final String regex = "<img.*?\\\">";
final String string = "Hello World <img src=\"https://dummyimage.com/300.png/09f/777\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/ff2\"> Random Text\nHello\nHello Random <img src=\"https://dummyimage.com/300.png/09f/888\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/2ff\">adaad\n";
final String replace = "";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
final String result = matcher.replaceAll(replace); // Here, how can I collect all the image tags in a list
Лично я бы не стал изобретать парсеры html заново. Не надо и не сделаешь так, как те, кто их зарабатывает на жизнь




Вы можете просто сделать это:
final List<String> result = new ArrayList<>();
while (matcher.find()) {
result.add(matcher.group());
}
и избавься от своего final String replace = "";
Мы можем разделить данную строку, используя так называемые Lookaheads и Lookbehinds (для получения дополнительной информации см. ссылку, приведенную ниже):
(?<=.)(?=<) — соответствует положению между любым символом и открывающей угловой скобкой < (т. е. захватывает пустую подстроку между любым символом и началом тега).
(?<=>)(?=.) — соответствует позиции между закрывающей угловой скобкой > и любым символом.
public static final Pattern ANGLE_BRACKETS =
Pattern.compile("(?<=.)(?=<)|(?<=>)(?=.)");
Используя этот шаблон, мы генерируем поток подстроки, наложенной на пустую строку на границе открывающих и закрывающих угловых скобок. А затем отфильтруйте строки, представляющие действительный тег изображения.
final String string = "Hello World <img src=\"https://dummyimage.com/300.png/09f/777\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/ff2\"> Random Text\nHello\nHello Random <img src=\"https://dummyimage.com/300.png/09f/888\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/2ff\">adaad\n";
List<String> imageTags = ANGLE_BRACKETS.splitAsStream(string)
.filter(str -> str.strip().matches("<img[^<]+>")) // verifying that a string is a valid image tag
.toList();
imageTags.forEach(System.out::println);
В регулярном выражении вам нужно позаботиться об открывающей угловой скобке < (не кавычках), чтобы захваченная подстрока содержала только один тег:
public static final Pattern IMG_TAG = Pattern.compile("img[^<]+>");
Используя метод Java 9 Matcher.results(), мы можем создать поток MatchResult объектов, которые содержат информацию о захваченных последовательностях в заданной строке. И чтобы получить совпадающую подстроку, мы можем использовать MatchResult.group().
final String string = "Hello World <img src=\"https://dummyimage.com/300.png/09f/777\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/ff2\"> Random Text\nHello\nHello Random <img src=\"https://dummyimage.com/300.png/09f/888\"> \nMy Name <img src=\"https://dummyimage.com/300.png/09f/2ff\">adaad\n";
List<String> imageTags = IMG_TAG.matcher(string).results() // Stream<MatchResult>
.map(MatchResult::group) // Stream<String>
.toList();
imageTags.forEach(System.out::println);
Вывод:
<img src = "https://dummyimage.com/300.png/09f/777">
<img src = "https://dummyimage.com/300.png/09f/ff2">
<img src = "https://dummyimage.com/300.png/09f/888">
<img src = "https://dummyimage.com/300.png/09f/2ff">
Не могли бы вы также предоставить отчеты об импорте?
@NitinKumar Конечно, вот ссылка на Online Demo (все необходимые импорты указаны вверху).
@NitinKumar Я понял, почему вы просили об импорте. Matcher.results() был добавлен с Java 9 (если вы используете Java 8, он будет недоступен). Я предоставил альтернативное решение, совместимое с Java 8, на основе Pattern.splitAsStream() (через минуту я объясню, как оно работает).
Вы можете использовать
#start,#endи#groupв классеMatcher, чтобы получить эту информацию. Это было бы вопросом повторения групп в вашем совпадении и добавления их в список самостоятельно. Обратите внимание, что если ваше регулярное выражение включает в себя более одного тега на группу (например,<img ...> ... </img>), вы столкнетесь с ограничениями регулярного выражения и, скорее всего, вам понадобится синтаксический анализатор html.