Java find()只在JUnit测试中查找最后一个匹配项

Java find()只在JUnit测试中查找最后一个匹配项,java,junit,Java,Junit,我有个奇怪的问题。我有一个Java方法,在我的程序中运行良好: /* * Extract all image urls from the html source code */ public void extractImageUrlFromSource(ArrayList<String> imgUrls, String html) { Pattern pattern = Pattern.compile("\\<[ ]*[iI][mM][gG][\t\n\r\f ]+.*

我有个奇怪的问题。我有一个Java方法,在我的程序中运行良好:

/*
* Extract all image urls from the html source code
*/
public void extractImageUrlFromSource(ArrayList<String> imgUrls, String html) {
    Pattern pattern = Pattern.compile("\\<[ ]*[iI][mM][gG][\t\n\r\f ]+.*[sS][rR][cC][ ]*=[ ]*\".*\".*>");
    Matcher matcher = pattern.matcher(html);
    while (matcher.find()) {
        imgUrls.add(extractImgUrlFromTag(matcher.group()));
    }
}
这个方法在我的java应用程序中运行良好。但每当我在JUnit测试中测试它时,它只会将最后一个url添加到ArrayList中

/**
 * Test of extractImageUrlFromSource method, of class ImageDownloaderProc.
 */
@Test
public void testExtractImageUrlFromSource() {
    System.out.println("extractImageUrlFromSource");
    String html = "<html><title>fdjfakdsd</title><body><img kfjd src=\"http://image1.png\">df<img dsd src=\"http://image2.jpg\"></body><img dsd src=\"http://image3.jpg\"></html>";
    ArrayList<String> imgUrls = new ArrayList<String>();
    ArrayList<String> expimgUrls = new ArrayList<String>();
    expimgUrls.add("http://image1.png");
    expimgUrls.add("http://image2.jpg");
    expimgUrls.add("http://image3.jpg");
    ImageDownloaderProc instance = new ImageDownloaderProc();
    instance.extractImageUrlFromSource(imgUrls, html);
    imgUrls.stream().forEach((x) -> {
        System.out.println(x);
    });
    assertArrayEquals(expimgUrls.toArray(), imgUrls.toArray());
}

是少年犯了错吗。请记住,它在我的应用程序中运行良好。

我希望我可以发表评论,因为我不确定这一点,但可能值得一提

这行代码看起来好像是从错误的数组中提取URL…您的意思是从expimgUrls而不是imgUrls中提取吗

instance.extractImageUrlFromSource(imgUrls, html);

我在Java教育中还没有走到这一步,所以我可能是不正确的……我只是查看了一下代码并注意到了它。我希望知道更多的人能给你一个可靠的答案

我认为正则表达式中存在一个问题:

  "\\<[ ]*[iI][mM][gG][\t\n\r\f ]+.*[sS][rR][cC][ ]*=[ ]*\".*\".*>"
这个问题或者至少有一个问题是我们首先遇到的。*。+和*元字符是贪婪的,这意味着它们将尝试匹配尽可能多的字符。在您的单元测试中,我认为发生的是,.*将所有内容匹配到输入字符串中的最后一个'src'

我怀疑这在应用程序中起作用的原因是输入数据不同。具体地说,我怀疑您正在输入文件上运行应用程序,其中每个img元素位于不同的行上。为什么这会有不同?事实证明,默认情况下。元字符与换行符不匹配

无论如何,使用正则表达式解析HTML通常被认为是个坏主意。首先,它非常脆弱。做很多这类事情的人倾向于使用合适的HTML解析器。。。像jsoup


引用:

expimgUrls是Junit所期望的ArrayList。assertArrayEquals将根据imgUrls的结果对其进行测试。我只想看看自己:[\t\n\r\f]+的原因是img中至少可以有一个空格。在这之后使用.*的原因是,有时您可以在需要使用不会消耗太多的内容替换.*之前,先放置图像标记的宽度、高度和alt属性。下面的例子也是如此。提示:他们不应该消费>。。。。。