文章目录
-
- 概览
- 常见表达式
-
- 手机号码
-
- [1. 通用手机号正则表达式](#1. 通用手机号正则表达式)
- [2. 匹配特定号段的手机号正则表达式](#2. 匹配特定号段的手机号正则表达式)
- [3. 注意事项](#3. 注意事项)
- [4. 示例代码](#4. 示例代码)
- 电子邮箱
-
- [1. 基本邮箱正则表达式](#1. 基本邮箱正则表达式)
- [2. 更严格的邮箱正则表达式](#2. 更严格的邮箱正则表达式)
- [3. Python中的邮箱正则表达式](#3. Python中的邮箱正则表达式)
- [4. 注意事项](#4. 注意事项)
- 身份证
- 年龄
-
- [1. 匹配整数年龄](#1. 匹配整数年龄)
- [2. 匹配带有单位的年龄](#2. 匹配带有单位的年龄)
- [3. 匹配年龄范围](#3. 匹配年龄范围)
- [4. 匹配带有单位和范围的年龄](#4. 匹配带有单位和范围的年龄)
- 注意事项
- 正则表达式在Java中的应用
-
- [1. 匹配简单的字符串](#1. 匹配简单的字符串)
- [2. 忽略大小写匹配](#2. 忽略大小写匹配)
- [3. 匹配电子邮件地址](#3. 匹配电子邮件地址)
- [4. 替换字符串中的模式](#4. 替换字符串中的模式)
概览
正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本处理工具,用于描述或匹配字符串搜索的模式。它广泛应用于各种编程语言中,如 Python、JavaScript、Java、Perl 等,用于文本搜索、替换、验证等操作。
正则表达式的基本组成
- 普通字符 :匹配它们自身的字符,例如
a
匹配字符a
。 - 特殊字符 :具有特殊含义的字符,例如
.
(匹配任意单个字符)、*
(匹配前一个字符0次或多次)、?
(匹配前一个字符0次或1次)等。 - 字符类 :用方括号
[]
包围的一组字符,匹配方括号内的任意字符。例如[abc]
匹配a
、b
或c
。 - 范围 :在字符类中使用连字符
-
表示字符范围。例如[a-z]
匹配任意小写字母。 - 元字符 :具有特殊含义的字符,如
.
、^
、$
、*
、+
、?
、{}
、|
、()
等。 - 转义字符 :使用反斜杠
\
来匹配元字符自身或具有特殊含义的字符。例如\.
匹配字符.
。 - 量词 :用于指定前一个字符或子模式出现的次数。
*
:0次或多次+
:1次或多次?
:0次或1次{n}
:恰好n次{n,}
:至少n次{n,m}
:至少n次,但不超过m次
正则表达式的基本语法
-
匹配任意字符 :
.
a.c
匹配abc
、adc
、a1c
等。
-
匹配字符集 :
[]
[abc]
匹配a
、b
或c
。[a-z]
匹配任意小写字母。[A-Z0-9]
匹配任意大写字母或数字。
-
匹配字符集的补集 :
[^]
[^abc]
匹配除a
、b
、c
之外的任意字符。
-
匹配开始和结束 :
^
和$
^abc
匹配以abc
开头的字符串。abc$
匹配以abc
结尾的字符串。
-
匹配单词边界 :
\b
\bcat\b
匹配单词cat
,但不匹配concatenate
。
-
分组和捕获 :
()
(abc)
匹配abc
并捕获为一个组。(\d{3})-(\d{2})-(\d{4})
匹配美国电话号码并捕获区号、前缀和号码。
-
或操作 :
|
a|b
匹配a
或b
。(cat|dog)
匹配cat
或dog
。
-
转义字符 :
\
\.
匹配字符.
。\(
匹配字符(
。\\
匹配字符\
。
-
量词 :
*
、+
、?
、{}
a*
匹配0个或多个a
。a+
匹配1个或多个a
。a?
匹配0个或1个a
。a{3}
匹配恰好3个a
。a{3,}
匹配至少3个a
。a{3,5}
匹配3到5个a
。
示例
-
匹配电子邮件地址:
regex[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
-
匹配URL:
regexhttps?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(\/[a-zA-Z0-9._\/%-]*)*
-
匹配IPv4地址:
regex((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])
正则表达式是一种强大的工具,但也可能变得非常复杂。通过学习和实践,可以逐步掌握其语法和技巧,提高文本处理效率。
常见表达式
手机号码
手机号正则表达式是用于匹配和验证手机号码格式的工具。以下是一些常见的手机号正则表达式及其解释:
1. 通用手机号正则表达式
-
模式 :
^1[3-9]\d{9}$
-
解释:
^
:表示字符串的开始。1
:表示手机号码以数字1开头。[3-9]
:表示手机号码的第二位数字必须是3到9之间的一个数字。\d{9}
:表示后面必须跟着9位数字。$
:表示字符串的结束。
这个正则表达式可以匹配中国大陆大多数运营商的手机号码格式。
2. 匹配特定号段的手机号正则表达式
有时候,你可能需要匹配特定运营商或特定号段的手机号码。例如:
- 移动手机号 :
^1(3[4-9]|5[0-27-9]|6[257]|7[28]|8[2-478]|98|47)\d{8}$
- 联通手机号 :
^1(3[0-2]|4[5]|5[56]|6[5]|7[156]|8[56])\d{8}$
- 电信手机号 :
^1(33|349|49|53|73|77|80|81|89|99|377|39|40|51|74|78|82|83|84|87|88|90|91|98)\d{8}$
这些正则表达式根据运营商或号段的不同而有所变化。
3. 注意事项
- 正则表达式的局限性:虽然正则表达式可以匹配大多数手机号码格式,但它们无法验证手机号码的真实性。要验证手机号码是否真实存在,通常需要使用额外的服务或数据库来查询。
- 更新正则表达式:随着时间的推移,新的手机号段可能会推出。因此,在实际应用中,可能需要根据最新的手机号规则来更新正则表达式。
4. 示例代码
以下是一个使用正则表达式验证手机号码的Java示例代码:
java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class PhoneNumberValidator {
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
public static boolean isValidPhoneNumber(String phoneNumber) {
if (phoneNumber == null || phoneNumber.isEmpty()) {
return false;
}
Matcher matcher = PHONE_PATTERN.matcher(phoneNumber);
return matcher.matches();
}
public static void main(String[] args) {
System.out.println(isValidPhoneNumber("13800138000")); // 输出: true
System.out.println(isValidPhoneNumber("12800138000")); // 输出: false, 因为第二位不是3-9
System.out.println(isValidPhoneNumber("1380013800")); // 输出: false, 因为长度不是11位
System.out.println(isValidPhoneNumber(null)); // 输出: false, 因为输入为null
}
}
这个示例代码定义了一个isValidPhoneNumber
方法,该方法使用正则表达式来验证手机号码的格式是否正确。
电子邮箱
邮箱正则表达式是用于匹配和验证电子邮件地址格式的工具。以下是一些常见的邮箱正则表达式及其解释:
1. 基本邮箱正则表达式
一个基本的邮箱正则表达式可能看起来像这样:
regex
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
^
表示字符串的开始。[a-zA-Z0-9._%+-]+
匹配用户名部分,允许小写字母、大写字母、数字、点(.)、下划线(_)、百分号(%)、加号(+)和减号(-)等字符,并且至少出现一次。@
是必须出现的分隔符。[a-zA-Z0-9.-]+
匹配域名部分,可以有字母、数字、点(.)和减号(-)。\.
匹配字面上的点(.),因为在正则表达式中,点是一个特殊字符,表示匹配任意单个字符,所以这里需要进行转义。[a-zA-Z]{2,}
匹配顶级域名部分,至少需要两个字母组成。$
表示字符串的结束。
2. 更严格的邮箱正则表达式
有些情况下,你可能需要一个更严格的正则表达式来确保电子邮件地址的格式更加准确。例如:
regex
^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,3}([\.][a-z]{2})?$
- 这个正则表达式要求电子邮件地址必须以一个小写字母开头。
- 用户名部分可以包含字母、数字、下划线(_)和减号(-),但不能以减号(-)结尾,也不能连续出现减号(-)。
- 域名部分也有类似的限制。
- 顶级域名部分至少有两个字母,可以有一个可选的附加顶级域名(如
.co.uk
)。
3. Python中的邮箱正则表达式
在Python中,你可以使用re
模块来执行正则表达式操作。以下是一个使用Python正则表达式验证电子邮件地址的示例:
python
import re
def is_valid_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
# 测试案例
emails = ['user@example.com', 'user.name+tag@sub.example.co.uk', 'invalid-email@.com']
for email in emails:
print(f"{email}: {is_valid_email(email)}")
4. 注意事项
- 正则表达式的局限性:虽然正则表达式可以匹配大多数电子邮件地址格式,但它们无法验证电子邮件地址的真实性。要验证电子邮件地址是否真实存在,通常需要使用额外的服务或数据库来查询。
- 更新正则表达式:随着时间的推移,新的电子邮件地址格式可能会出现。因此,在实际应用中,可能需要根据最新的电子邮件地址规则来更新正则表达式。
综上所述,邮箱正则表达式是一种强大的工具,用于匹配和验证电子邮件地址的格式。你可以根据自己的需求选择适合的正则表达式,并在实际应用中进行相应的调整和优化。
身份证
身份证正则表达式是用于匹配和验证中国大陆身份证号码的工具。中国大陆身份证号码分为15位和18位两种,但目前15位身份证号码已经停用,因此现代应用中主要关注的是18位身份证号码的正则表达式。
以下是一个常见的18位身份证号码的正则表达式:
regex
^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|(3[0-1]))\d{3}[0-9Xx]$
这个正则表达式的结构可以分解为以下几个部分:
^[1-9]
:身份证号码的第一位数字不能是0,因此这里用[1-9]
来匹配。\d{5}
:接下来的五位数字是地区码,用\d{5}
来匹配。(18|19|20)\d{2}
:这部分匹配出生年份,由于目前年份范围是1900年到2099年(尽管2099年尚未到来,但为了兼容性,通常会将正则表达式设置为能够匹配到这个范围),因此用(18|19|20)\d{2}
来匹配。((0[1-9])|(1[0-2]))
:这部分匹配月份,用(0[1-9])
来匹配1月到9月,用(1[0-2])
来匹配10月到12月。(([0-2][1-9])|(3[0-1]))
:这部分匹配日期,用([0-2][1-9])
来匹配1日到29日,用(3[0-1])
来匹配30日和31日。注意,这里并没有对每个月的天数进行严格的校验,因为不同月份的天数不同,且2月还有闰年的情况。但在这个正则表达式中,为了简化,通常不会包含这些复杂的校验逻辑。\d{3}
:这部分匹配顺序码,是三位数字,用\d{3}
来匹配。[0-9Xx]$
:最后一位是校验码,可以是数字0-9或者字母X(代表罗马数字10),用[0-9Xx]
来匹配,并且用$
来确保这是字符串的结尾。
需要注意的是,虽然这个正则表达式可以匹配大多数有效的身份证号码,但它并不能验证身份证号码的真实性。要验证身份证号码是否真实存在,还需要进行额外的算法校验,比如计算校验码是否正确等。
此外,由于身份证号码的格式可能会随着时间的推移而发生变化(尽管这种变化非常罕见),因此在实际应用中,可能需要根据最新的身份证号码规则来更新正则表达式。
年龄
年龄正则表达式是用于匹配和验证年龄格式的工具。不过,与电子邮件或身份证号码等具有固定格式的字符串不同,年龄的表达方式可能更加灵活。通常,年龄可以是整数、整数范围、带有"岁"等单位的字符串等。
以下是一些常见的年龄正则表达式及其解释:
1. 匹配整数年龄
如果你想匹配一个简单的整数年龄(例如,18、25、30等),可以使用以下正则表达式:
regex
^\d{1,3}$
^
表示字符串的开始。\d{1,3}
匹配1到3位的数字(假设年龄不会超过999岁)。$
表示字符串的结束。
2. 匹配带有单位的年龄
如果你想匹配带有"岁"等单位的年龄(例如,18岁、25岁等),可以使用以下正则表达式:
regex
^\d{1,3}岁$
^\d{1,3}
匹配1到3位的数字。岁$
匹配字面上的"岁"字符,并确保它是字符串的结尾。
3. 匹配年龄范围
如果你想匹配一个年龄范围(例如,18-25、25-35等),可以使用以下正则表达式:
regex
^\d{1,3}-\d{1,3}$
^\d{1,3}
匹配范围的起始年龄,1到3位的数字。-
匹配字面上的连字符。\d{1,3}$
匹配范围的结束年龄,1到3位的数字。
4. 匹配带有单位和范围的年龄
如果你想匹配一个带有单位和范围的年龄(例如,18-25岁、25-35周岁等),可以使用更复杂的正则表达式:
regex
^(\d{1,3}-\d{1,3}|\d{1,3})(岁|周岁)?$
^
表示字符串的开始。(\d{1,3}-\d{1,3}|\d{1,3})
匹配一个年龄范围或一个单独的年龄。(岁|周岁)?
匹配可选的"岁"或"周岁"单位。$
表示字符串的结束。
注意事项
-
正则表达式的局限性:虽然正则表达式可以匹配大多数年龄格式,但它们无法验证年龄的真实性。例如,它们无法确定一个给定的年龄是否在合理的生命范围内。
-
更新正则表达式:如果应用程序需要处理更复杂的年龄格式(例如,带有小数点的年龄、带有文字描述的年龄等),你可能需要根据具体需求来更新正则表达式。
-
年龄验证:在实际应用中,除了使用正则表达式进行格式匹配外,通常还需要进行额外的逻辑验证来确保年龄的合理性和真实性。例如,你可以检查年龄是否在合理的范围内(例如,0到120岁之间),或者与用户的出生日期进行比较来计算实际年龄。
正则表达式在Java中的应用
在Java中,正则表达式主要通过java.util.regex
包中的类来实现,其中最重要的类是Pattern
和Matcher
。Pattern
类用于编译正则表达式,并创建一个匹配模式;Matcher
类用于对输入字符串进行匹配操作。
下面是一些使用Java正则表达式的例子:
1. 匹配简单的字符串
假设我们想要匹配字符串中是否包含单词"hello":
java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexExample {
public static void main(String[] args) {
String input = "Hello world!";
String regex = "hello"; // 注意:正则表达式是大小写敏感的
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
boolean matches = matcher.find(); // 查找是否存在匹配
if (matches) {
System.out.println("Found match!");
} else {
System.out.println("No match found.");
}
}
}
在这个例子中,由于输入字符串是"Hello world!"(注意H是大写的),而正则表达式是"hello"(小写的),所以不会找到匹配项。
2. 忽略大小写匹配
为了忽略大小写,我们可以在编译正则表达式时使用Pattern.CASE_INSENSITIVE
标志:
java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexExample {
public static void main(String[] args) {
String input = "Hello world!";
String regex = "hello";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
boolean matches = matcher.find();
if (matches) {
System.out.println("Found match (case insensitive)!");
} else {
System.out.println("No match found.");
}
}
}
这次,由于我们使用了忽略大小写的标志,所以能够找到匹配项。
3. 匹配电子邮件地址
下面是一个更复杂的例子,用于匹配电子邮件地址:
java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class EmailRegexExample {
public static void main(String[] args) {
String input = "Please contact us at support@example.com for more information.";
String regex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("Found email: " + matcher.group());
}
}
}
在这个例子中,正则表达式用于匹配电子邮件地址的常用模式。matcher.find()
方法用于在输入字符串中查找所有匹配项,而matcher.group()
方法用于返回当前匹配的子字符串。
4. 替换字符串中的模式
除了查找匹配项外,我们还可以使用正则表达式来替换字符串中的模式。例如,将字符串中的所有空格替换为下划线:
java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ReplaceRegexExample {
public static void main(String[] args) {
String input = "This is a test string.";
String regex = " "; // 匹配空格
String replacement = "_"; // 替换为下划线
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
String result = matcher.replaceAll(replacement);
System.out.println("Replaced string: " + result);
}
}
在这个例子中,matcher.replaceAll(replacement)
方法用于将输入字符串中所有匹配正则表达式的部分替换为指定的替换字符串。
通过这些例子,你可以看到Java中正则表达式的强大功能,以及如何使用Pattern
和Matcher
类来编译和使用正则表达式。