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

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对象。例如:

Pattern pattern = Pattern.compile("a*b");

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

Matcher matcher = pattern.matcher("aaaaab");

2.2 Matcher的使用

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

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

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

3. 示例

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

3.1 匹配邮箱地址

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 替换字符串中的特定内容

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 加减乘除计算

// 正则表达式匹配数字和运算符
			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中的一个重要概念。通过在正则表达式中使用括号来创建捕获组,可以方便地提取匹配的特定部分。例如:

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 贪婪与勉强匹配

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

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)的语法来创建命名捕获组,方便管理和提取数据。例如:

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 验证密码强度

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

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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

司徒阿宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值