奇思妙想录 我有两个忠实的助手,一个是我的耐心,另一个就是我的双手。——蒙田
歌曲封面 未知作品

萌ICP备20248808号

津ICP备2023004371号-2

网站已运行 2 年 5 天 19 小时 44 分

Powered by Typecho & Sunny

0 online

Title

Java字符串匹配:Pattern与Matcher类介绍

IhaveBB

·

Article
⚠️ 本文最后更新于2024年01月21日,已经过了180天没有更新,若内容或图片失效,请留言反馈
AI摘要:Java中的`Pattern`类用于编译正则表达式,而`Matcher`类用于对字符串进行匹配操作。通过`Pattern.compile()`方法创建`Pattern`对象,然后使用`matcher()`方法创建`Matcher`对象。`Matcher`类提供`find()`、`group()`等方法来查找和获取匹配的子串。本文通过匹配邮箱地址、替换字符串内容、执行数学运算等示例,展示了`Pattern`和`Matcher`的使用方法。同时,介绍了捕获组、贪婪与勉强匹配的概念,以及如何使用命名捕获组和正则表达式来验证密码强度。

Powered by AISummary.

1. 介绍

Java中的Pattern类是一个正则表达式的编译表示。它定义了一个模式(pattern),这个模式可以用于创建Matcher对象,用来匹配输入的字符串。Matcher类则用于对字符串进行匹配操作。

1.1 Pattern

Pattern类的主要作用是将正则表达式编译成一个可供Matcher类使用的模式。它提供了多种方法,用于将正则表达式字符串编译为Pattern对象。此外,它还提供了一些静态方法,比如matches()用于匹配字符串是否符合给定的模式。

1.2 Matcher

Matcher类是Pattern类的实例化对象,用于对输入字符串进行匹配操作。它提供了诸如find()group()start()end()等方法,用于在输入字符串中查找匹配模式的子串,并提供有关匹配信息的详细数据。

2. 使用方法

2.1 Pattern的使用

要使用Pattern类,首先需要使用其静态方法compile()将正则表达式编译为一个Pattern对象。例如:

♾️ java 代码:
Pattern pattern = Pattern.compile("a*b");

这样就创建了一个匹配零个或多个字符'a'后跟字符'b'的模式。接下来,可以使用这个Pattern对象创建一个Matcher对象:

♾️ java 代码:
Matcher matcher = pattern.matcher("aaaaab");

2.2 Matcher的使用

有了Matcher对象,就可以对输入的字符串进行匹配操作。可以使用find()方法查找匹配的子串,并使用group()方法获取匹配的子串。例如:

♾️ java 代码:
while (matcher.find()) {
    System.out.println("Found match at: " + matcher.start() + " - " + matcher.end());
    System.out.println("Matched substring: " + matcher.group());
}

这段代码将输出匹配到的子串在输入字符串中的起始和结束位置,并打印匹配到的子串内容。

3. 示例

让我们通过一些示例来演示PatternMatcher的使用。

3.1 匹配邮箱地址

♾️ java 代码:
String input = "Emails: example1@email.com, example2@email.com";
Pattern emailPattern = Pattern.compile("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b");
Matcher emailMatcher = emailPattern.matcher(input);

while (emailMatcher.find()) {
    System.out.println("Found email: " + emailMatcher.group());
}
  • \\b: 表示单词边界,匹配单词的开始或结束。
  • [A-Za-z0-9._%+-]+: 匹配电子邮件地址的用户名部分,可以包含字母、数字、以及一些特殊字符(._%+-),+表示匹配前面的字符集至少一次或多次。
  • @: 匹配电子邮件地址中的 @ 符号。
  • [A-Za-z0-9.-]+: 匹配电子邮件地址的域名部分,可以包含字母、数字、.-,同样使用 + 表示匹配至少一次或多次。
  • \\.: 匹配电子邮件地址中的 . 符号,需要使用 \\ 进行转义,表示匹配实际的点号字符。
  • [A-Z|a-z]{2,}: 匹配顶级域名,即邮件地址的后缀部分,比如 .com.org 等。{2,}表示至少匹配两个或更多字母,[A-Z|a-z]表示大写或小写字母的集合。
  • \\b: 再次使用单词边界,表示匹配单词的结束。

3.2 替换字符串中的特定内容

♾️ java 代码:
String input = "The cat and the hat";
Pattern pattern = Pattern.compile("\\b cat \\b");
Matcher matcher = pattern.matcher(input);
String replacedString = matcher.replaceAll("dog");

System.out.println("Replaced string: " + replacedString);
  • \\b: 表示单词边界,确保匹配的是单独的单词而不是单词的一部分。
  • cat: 匹配要查找的确切字符序列,这里是"cat"。

3.3 加减乘除计算

♾️ java 代码:
// 正则表达式匹配数字和运算符
            String regex = "([\\d.]+)\\s*([-+*/])\\s*([\\d.]+)";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(expression);
            if(matcher.find())
            {
                double operand1 = Double.parseDouble(matcher.group(1));
                String operator = matcher.group(2);
                double operand2 = Double.parseDouble(matcher.group(3));
                // 根据运算符计算结果
                switch(operator)
                {
                    case "+":
                        return operand1 + operand2;
                    case "-":
                        return operand1 - operand2;
                    case "*":
                        return operand1 * operand2;
                    case "/":
                        return operand1 / operand2;
                    default:
                        // 处理其他运算符
                        break;
                }
            }
  • ([\\d.]+): 这个部分匹配一个数字,包括小数点,[\\d.]表示可以匹配数字0到9和小数点".",+表示匹配一个或多个前面的字符。整个括号表示捕获这个数字。
  • \\s*: 这部分匹配零个或多个空白字符,包括空格、制表符等。
  • ([-+*/]): 这个部分匹配一个运算符号,可以是加号、减号、乘号或除号。括号里的内容表示捕获这个运算符号。
  • \\s*: 再次匹配零个或多个空白字符。
  • ([\\d.]+): 类似第一个部分,再次匹配一个数字,也会被捕获。

4. 深入了解

4.1 捕获组

捕获组是PatternMatcher中的一个重要概念。通过在正则表达式中使用括号来创建捕获组,可以方便地提取匹配的特定部分。例如:

♾️ java 代码:
Pattern pattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher matcher = pattern.matcher("Phone numbers: 123-456-7890, 987-654-3210");

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    System.out.println("Area code: " + matcher.group(1));
    System.out.println("Prefix: " + matcher.group(2));
    System.out.println("Suffix: " + matcher.group(3));
}

4.2 贪婪与勉强匹配

量词(比如*+?)默认是贪婪模式,会尽可能多地匹配字符。但你也可以通过在量词后面加上?来实现勉强模式,即匹配尽可能少的字符。例如:

♾️ java 代码:
String text = "aaaaaa";
Pattern greedyPattern = Pattern.compile("a+");
Pattern reluctantPattern = Pattern.compile("a+?");

Matcher greedyMatcher = greedyPattern.matcher(text);
Matcher reluctantMatcher = reluctantPattern.matcher(text);

while (greedyMatcher.find()) {
    System.out.println("Greedy match: " + greedyMatcher.group());
}

while (reluctantMatcher.find()) {
    System.out.println("Reluctant match: " + reluctantMatcher.group());
}

5. 示例扩展

5.1 使用命名捕获组

Java支持使用(?<name>regex)的语法来创建命名捕获组,方便管理和提取数据。例如:

♾️ java 代码:
Pattern pattern = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher matcher = pattern.matcher("Date: 2023-11-22");

while (matcher.find()) {
    System.out.println("Year: " + matcher.group("year"));
    System.out.println("Month: " + matcher.group("month"));
    System.out.println("Day: " + matcher.group("day"));
}
  • (?<year>\\d{4}): 这部分使用了命名捕获组,(?<year> 表示开始一个名为 "year" 的捕获组。\\d{4} 匹配四个数字字符,因此它匹配年份的部分。
  • -(?<month>\\d{2}): 同样是一个命名捕获组,(?<month> 表示开始一个名为 "month" 的捕获组。\\d{2} 匹配两个数字字符,匹配月份的部分。
  • -(?<day>\\d{2}): 也是一个命名捕获组,(?<day> 表示开始一个名为 "day" 的捕获组。\\d{2} 匹配两个数字字符,匹配日期的部分。

5.2 验证密码强度

使用正则表达式来验证密码强度是一个常见的应用。例如:

♾️ java 代码:
String password = "Passw0rd!";
Pattern pattern = Pattern.compile("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,}$");
Matcher matcher = pattern.matcher(password);

if (matcher.matches()) {
    System.out.println("Strong password!");
} else {
    System.out.println("Weak password!");
}
  • ^: 表示匹配字符串的开始位置。
  • (?=.*[0-9]): 这个部分是一个正向前视断言,用于确认字符串中至少包含一个数字。
  • (?=.*[a-z]): 类似于上面,确认字符串中至少包含一个小写字母。
  • (?=.*[A-Z]): 同样是一个断言,确认字符串中至少包含一个大写字母。
  • (?=.*[@#$%^&+=!]): 这个断言用于确认字符串中至少包含特殊字符,如 @、#、$、%、^、&、+、= 或 !。
  • (?=\\S+$): 这是一个断言,用于确认整个字符串中不包含空格。
  • .{8,}: 匹配至少包含8个或更多字符。
  • $: 表示匹配字符串的结束位置。

注意!在正则表达式中,^ 在不同的位置有不同的含义

  • 当它在字符集合 [ ] 内部使用时,它表示字符集的取反,即匹配不在该字符集内的字符。例如 [^0-9] 表示匹配除了数字之外的任何字符。
  • ^ 在正则表达式的开头使用时,它表示匹配字符串的开头位置。它不是反义的意思,而是指定匹配的起始位置。

总结

如上介绍了Pattern和Matcher的几个基本用法,并介绍了一些正则表达式的写法

现在已有 0 条评论,0 人点赞
Comment
发表
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主