Matcher.find()只在JUnit Test中找到最后一个匹配项

时间:2014-08-10 03:57:18

标签: 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 ]+.*[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());
}

JUnit是否有故障。请记住,它在我的应用程序中运行良好。

2 个答案:

答案 0 :(得分:0)

我希望我能发表评论,因为我对此不太确定,但值得一提......

这一行看起来像是从错误的数组中提取URL ...你的意思是从expimgUrls中提取而不是imgUrls吗?

instance.extractImageUrlFromSource(imgUrls, html);

我在Java教育中没有这么做,所以我可能不正确......我只是查看代码并注意到它。我希望知道更多的人能够给你一个坚实的答案!

答案 1 :(得分:0)

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

  "\\<[ ]*[iI][mM][gG][\t\n\r\f ]+.*[sS][rR][cC][ ]*=[ ]*\".*\".*>"

问题(或至少一个问题)我们是第一个.*+*元字符是贪婪的,这意味着它们将尝试匹配尽可能多的字符。在您的单元测试中,我认为发生的事情是.*匹配输入字符串中 last 'src'的所有内容。

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


对于它的价值,使用正则表达式“解析”HTML通常被认为是一个坏主意。首先,它非常脆弱。做很多这类事情的人倾向于使用正确的HTML解析器......比如“jsoup”。

参考:RegEx match open tags except XHTML self-contained tags