java - 这个 group() 如何捕捉文本?

标签 java regex

我遇到过这个 Hackerrank 问题,正则表达式应该匹配 HTML 标签之间的字符串。正则表达式和字符串是

String str="<h1>Hello World!</h1>";
String regex="<(.+)>([^<]+)</\\1>";

另外,如果“str”有多个 HTML 标签,如 String str="<h1><h1>Hello World!</h1></h1>" 怎么办?以及如何([^<]+)捕获这个“str”。

我的问题是如何([^<]+)匹配 'str' 而不是 ([a-zA-Z]+) .

这里是完整的源代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/* Solution assumes we can't have the symbol "<" as text between tags */
public class Solution{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int testCases = Integer.parseInt(scan.nextLine());

        while (testCases-- > 0) {
            String line = scan.nextLine();

            boolean matchFound = false;
            Pattern r = Pattern.compile(regex);
            Matcher m = r.matcher(line);

            while (m.find()) {
                System.out.println(m.group(2));
                matchFound = true;
            }
            if ( ! matchFound) {
                System.out.println("None");
            }
        }
    }
}

如果我问这个问题是愚蠢的,请不要介意,在此先感谢您!

最佳答案

假定格式正确的 HTML 输入,此正则表达式保证您的字符串仅包含一个标记。

初始<(.+)>捕获您的标签的名称。捕获组还将获得它可以获得的任何属性。自 +是一个贪婪的量词,如果可以的话,它会捕获多个标签。

尾随</\\1>与第一组捕获的任何东西相匹配。这就是为什么,如果您的 HTML 格式正确,表达式将不会捕获多个标签或具有属性的标签:

  • 开始标记 <h1> , 结束标记 </h1>
  • 开始标记 <h1 attr="value"> , 结束标记 </h1> , 但期待 </h1 attr="value">
  • 开始标记 <h1><h2> , 结束标记 </h2></h1> , 但期待 </h1><h2>

这就是为什么标签可以与 .+ 匹配的原因相当安全,而内容必须与 [^<]+ 匹配.您要确保不在内容中获取任何停留标签,但允许使用任何其他字符。 [^<]+ (发音为“不是 <,至少一次)允许像 ! 这样的事情,而 [A-za-z] 肯定不会。

关于java - 这个 group() 如何捕捉文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54432799/

相关文章:

java - 如何在GET请求中传递postman中的列表并进入GetMapping

java - 使用正则表达式将字符串拆分为 3 部分

javascript - 匹配一个单词,除非它前面有等号?

regex - Python : Count items, 将计数存储为变量,用于将字符串替换为外部文件中的项目数的语句

java - 无法在 Java API 中运行 Tensorflow 预测

java - 错误 NoClassDefFoundError/ClassNotFoundException

python - 使用 fnmatch 匹配文件名的 2 部分

PHP preg_replace_callback,仅替换 1 个反向引用?

java - 在 servlet 中启用 CORS

Java 基于泛型做不同的事情