Java matcher.matches() 返回 false,但应该返回 true。

5
所以我遇到了一个问题,我需要在字符串中检查简单的开始和结束HTML标签。对于开始标签,我没有遇到任何问题,但是当我尝试找到结束标签时,我遇到了一些问题。
private Pattern pattern;
private Matcher matcher;
private Pattern endPattern;
private Matcher endMatcher;

private static final String HTML_TAG_PATTERN = "<([a-zA-Z]+)>";
public boolean hasCorrectHTML(String checking)
{
    boolean ret=true;
    pattern=Pattern.compile(HTML_TAG_PATTERN);
    matcher=pattern.matcher(checking);

    while(matcher.find() && ret)
    {
        String htmlEndTag="</"+matcher.group(1)+">";

        endPattern=Pattern.compile(htmlEndTag);
        endMatcher=endPattern.matcher(checking.substring(matcher.end()));

        ret=endMatcher.matches();
    }

    return ret;
}

在上面的代码中,我找到了第一个标签,然后继续寻找结束标签。我知道这个设置可能会有一些未来的问题,这还在进行中。然而,检查结束标签的部分不起作用。就我所看到的逻辑来说,应该是正确的。我将标签传入第二个模式中,并使用第二个匹配器来检查是否匹配。 我的文本字符串是"<b>this test</b>"。它可以很好地检测到<b>,但当我检查</b>是否匹配时,它总是返回false。我已经向同事们询问过为什么会发生这种情况,但他们也无法解释。我不知道为什么会发生这种情况,有什么想法吗?我在这里漏掉了什么?

4
matches()方法用于测试整个字符串是否与模式相匹配。像您正确地使用find()方法一样,可以使用该方法找到开标签。或者更好的方法是使用像JSoup这样的真正的HTML解析器。对于HTML解析,使用正则表达式是死路一条。 - JB Nizet
好的,这很有道理。我会使用真正的HTML解析器,但是出于这个目的,我被特别告知要以这种方式做。我知道这很愚蠢,我也不同意,但这并不总是关于我。 - Devvy
2个回答

6

好的,这个问题已经被JB Nizet解答了,但是我应该使用endMatcher.find()代替endMatcher.matches(),因为.matches()检查整个字符串是否与正则表达式匹配,而.find()检查与正则表达式匹配的字符串部分。


3

我没有完全理解你的问题,也不知道是否能解决你的问题,如果不能,请给我一些例子以便快速理解你的问题。

private Pattern pattern;
private Matcher matcher;
private Pattern endPattern;
private Matcher endMatcher;

private static final String HTML_TAG_PATTERN = "<([a-zA-Z]+)>[^<]*";
public boolean hasCorrectHTML(String checking)
{
    boolean ret=true;
    pattern=Pattern.compile(HTML_TAG_PATTERN);
    matcher=pattern.matcher(checking);

    while(matcher.find() && ret)
    {
        String htmlEndTag="</"+matcher.group(1)+">";

        endPattern=Pattern.compile(htmlEndTag);

        String endChecking = checking.substring(matcher.end());
        endMatcher=endPattern.matcher(endChecking);

        ret=endMatcher.matches();
    }

    return ret;
}

好的,假设我通过了<b>这个测试</b>。我的第一个HTML模式会找到开始标签(<b>)。如果找到任何内容,那么在这种情况下它会进入while循环,它会获取第一个查找的内容并为其创建一个结束标签检查,如</b>。然后它将检查字符串的其余部分是否具有该结束标记。问题是我正在使用.matches()而不是.find(),就像@JB_Nizet提到的那样,.matches()检查整个字符串是否为</b>,而.find()检查每个单独的</b>。 - Devvy
好的,无论如何,只要将 HTML_TAG_PATTERN 从 "<([a-zA-Z]+)>" 更改为 "<([a-zA-Z]+)>[^<]*",它就能正常工作。 - JIE WANG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接