【问题标题】:Collect part of string in a List in Java在Java中的List中收集部分字符串
【发布时间】:2022-11-16 00:33:26
【问题描述】:

有一个用例,我有一个很长的字符串,它可以包含许多 <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

【问题讨论】:

  • 您可以使用Matcher类下的#start#end#group来提取这些信息。这将是迭代匹配中的组,然后自己将它们添加到列表中的问题。请注意,如果您的正则表达式在每个组中包含多个标签(例如 &lt;img ...&gt; ... &lt;/img&gt;,您会遇到正则表达式的限制,并且可能需要一个 html 解析器。
  • 就个人而言,我不会尝试重新发明 html 解析器。没有必要,你不会像那些以写它们为生的人那样做

标签: java java-8


【解决方案1】:

你可以简单地这样做:

final List<String> result = new ArrayList<>();
while (matcher.find()) {
     result.add(matcher.group());
}

并摆脱你的final String replace = "";

【讨论】:

    【解决方案2】:

    使用Matcher.results()

    在正则表达式中,您需要关心左尖括号&lt;(不是引号),以确保捕获的子字符串仅包含一个标签:

    public static final Pattern IMG_TAG = Pattern.compile("img[^<]+>");
    

    使用Matcher.results(),我们可以创建一个MatchResult对象流,其中包含有关给定字符串中捕获序列的信息。而要获取匹配的子串,我们可以使用MatchResult.group()

    final String string = "Hello World <img src="https://dummyimage.com/300.png/09f/777"> 
    My Name <img src="https://dummyimage.com/300.png/09f/ff2"> Random Text
    Hello
    Hello Random <img src="https://dummyimage.com/300.png/09f/888"> 
    My Name <img src="https://dummyimage.com/300.png/09f/2ff">adaad
    ";
        
    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">
    

    A link to Online Demo

    【讨论】:

    • 您能否也提供进口声明?
    • @NitinKumar 当然,这是Online Demo 的链接(所有必需的导入都在顶部指定).
    猜你喜欢
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多