在实际编写程序的过程中,我们可能会遇到验证用户输入的数据是否符合特定的格式要求之类的问题:
010-1234567
,123ABC456
,13510001000
等;[email protected]
,test#example
等;12:34
,09:60
,99:99
等。在未引入正则表达式的前提下,一种直观的想法是通过程序判断,这种方法需要为每种用例创建规则,然后用代码实现。比如,如何判断字符串是否是有效的电话号码的代码:
public static boolean isValidPhoneNumber(String phoneNumber) {
// 判断号码长度是否在合理范围内
if (phoneNumberWithoutHyphen.length() < 7 || phoneNumberWithoutHyphen.length() > 11) {
return false;
}
// 判断号码中是否有非数字字符
for (char c : phoneNumberWithoutHyphen.toCharArray()) {
if (!Character.isDigit(c)) {
return false;
}
}
// 判断号码中是否有连续的连字符
if (phoneNumber.contains("--")) {
return false;
}
return true;
}
事实上,上述代码仅仅做了非常粗略的判断,并未考虑首位数字不能为0
等更详细的情况。除了判断手机号,我们还需要判断电子邮件地址、电话、邮编等等。可想而知,为每一种判断逻辑编写代码实在是太繁琐了。
为了避免这种情况,我们引入了正则表达式。正则表达式可以用字符串来描述规则,并用来匹配字符串。例如,判断手机号,我们用正则表达式^(\\d{3,4}-?)?\\d{7,8}$
:
public static boolean isValidPhoneNumber(String phoneNumber) {
// 定义电话号码的正则表达式模式
String regex = "^(\\d{3,4}-?)?\\d{7,8}$";
// 创建Pattern对象
Pattern pattern = Pattern.compile(regex);
// 创建Matcher对象
Matcher matcher = pattern.matcher(phoneNumber);
// 使用Matcher的matches方法进行匹配判断
return matcher.matches();
}
正则表达式是一套标准,它可以用于任何语言。Java标准库的
java.util.regex
包内置了正则表达式引擎,在Java程序中使用正则表达式非常简单。
正则表达式(Regular Expressions,简称正则或Regex)是一种强大的文本匹配和处理工具,用于在字符串中查找、匹配和替换特定模式的文本。
正则表达式不仅可以在编程时使用,也可以在word、IDE编辑器等软件的搜索和替换窗口中使用
正则表达式的主要目的是为了解决以下问题:
正则表达式的语法规则如下:
\
来表示字面含义。常见的特殊字符包括:. ^ $ * + ? { } [ ] \ | ( )
。[]
表示一个字符类,表示在此位置可以匹配方括号中的任意字符。例如,[abc]
表示可以匹配字符 a
、b
或 c
。-
,可以表示一个字符范围。例如,[0-9]
表示可以匹配任意数字。^
,可以表示排除的字符类。例如,[^0-9]
表示可以匹配任意非数字字符。\
加上一个预定义字符表示一些常见的字符类。例如,\d
表示任意数字,\w
表示任意字母、数字和下划线。*
(零次或多次),+
(一次或多次),?
(零次或一次),{n}
(恰好 n 次),{n,}
(至少 n 次),{n,m}
(至少 n 次,至多 m 次)。()
表示一个子表达式,将一组字符视为一个整体,并可以应用量词或其他操作符。例如,(abc)+
表示连续出现一次或多次的字符串 “abc”。|
表示多个子表达式之间的选择,匹配其中任意一个。例如,abc|def
表示匹配 “abc” 或 “def”。^
表示字符串的开始,用 $
表示字符串的结尾。例如,^abc
表示匹配以 “abc” 开始的字符串。以上是正则表达式的基本语法规则。正则表达式提供了丰富的功能,可以根据不同的需求进行组合和扩展。然而,由于正则表达式的语法较为复杂和灵活,对于复杂的模式描述,可能需要一定的学习和练习才能熟练运用。
正则表达式匹配默认使用贪婪匹配,可以使用?
表示对某一规则进行非贪婪匹配。
具体详情可以参考非贪婪匹配 - 廖雪峰的官方网站 (liaoxuefeng.com)
在Java中,String.matches()
方法要求整个字符串与正则表达式完全匹配。示例代码如下:
public class StringMatchesExample {
public static void main(String[] args) {
String regex = "[A-Za-z]+\\d+"; // 匹配至少一个字母后面跟着至少一个数字的模式
String str1 = "Ab123"; // 符合正则表达式
String str2 = "HelloWorld"; // 不符合正则表达式
String str3 = "12345"; // 不符合正则表达式
System.out.println("str1 matches regex: " + str1.matches(regex));
System.out.println("str2 matches regex: " + str2.matches(regex));
System.out.println("str3 matches regex: " + str3.matches(regex));
}
}
需要注意的是:正则表达式在Java代码中也是一个字符串,所以,对于正则表达式a\&c
来说,对应的Java字符串是"a\\&c"
,因为\
也是Java字符串的转义字符,两个\\
实际上表示的是一个\
。
如果你想要在字符串中查找是否包含符合正则表达式的部分,你可以使用 Pattern
类和 Matcher
类来实现更灵活的匹配操作。事实上,String.matches()
方法内部调用的就是Pattern
和Matcher
类的方法。
在 java.util.regex
中,Pattern
类和 Matcher
类是用于处理正则表达式的两个关键类。Pattern
类用于编译和表示正则表达式,而 Matcher
类则用于在文本中执行匹配操作。下面是一个简单的示例代码,演示如何使用 Pattern
和 Matcher
类进行匹配:
import java.util.regex.*;
public class PatternMatcherExample {
public static void main(String[] args) {
String regex = "\\b\\d{3}-\\d{4}\\b"; // 匹配形如 xxx-xxxx 的电话号码模式
String text = "这是我的电话号码:123-4567,你的电话号码是:987-6543。";
// 创建 Pattern 对象
Pattern pattern = Pattern.compile(regex);
// 创建 Matcher 对象
Matcher matcher = pattern.matcher(text);
// 查找匹配的电话号码
while (matcher.find()) {
System.out.println("找到匹配的电话号码:" + matcher.group());
}
}
}
输出结果为:
找到匹配的电话号码:123-4567
找到匹配的电话号码:987-6543
在上面的示例中,我们使用正则表达式 \\b\\d{3}-\\d{4}\\b
,该正则表达式用于匹配形如 xxx-xxxx
的电话号码模式。其中,\\b
表示单词边界,确保电话号码前后不会与其他字符连在一起;\\d{3}
表示匹配 3 个数字,-
表示匹配一个连字符,\\d{4}
表示匹配 4 个数字。
接着,我们创建了 Pattern
对象并编译正则表达式。然后,使用 Matcher
对象来在文本中执行匹配操作,matcher.find()
方法用于查找匹配的子串。如果找到匹配的电话号码,我们通过 matcher.group()
方法来获取匹配的子串,并输出它们。
matcher.group()
方法也可以和分组匹配结合在一起使用。
正则表达式简介 - 廖雪峰的官方网站 (liaoxuefeng.com)
使用正则表达式 - Visual Studio (Windows) | Microsoft Learn