欢迎使用 Java 中的正则表达式。它在 Java 中也称为 Regex。当我开始编程时,Java 正则表达式对我来说是一场噩梦。本教程旨在帮助您掌握 Java 中的正则表达式。我也会回到这里来刷新我的 Java Regex 学习。
java 中的正则表达式为字符串定义了一个模式。正则表达式可用于搜索、编辑或操作文本。正则表达式不是特定于语言的,但每种语言略有不同。Java 中的正则表达式与 Perl 最相似。
Java Regex 类存在于java.util.regex
包含三个类的包中:
- Pattern :
Pattern
object 是正则表达式的编译版本。模式类没有任何公共构造函数,我们使用它的公共静态方法compile
通过传递正则表达式参数来创建模式对象。 - Matcher:
Matcher
是将输入字符串模式与创建的模式对象相匹配的 java 正则表达式引擎对象。Matcher 类没有任何公共构造函数,我们使用模式对象matcher
方法获得一个 Matcher 对象,该方法将输入字符串作为参数。然后我们使用matches
根据输入字符串是否匹配正则表达式模式返回布尔结果的方法。 - PatternSyntaxException:
PatternSyntaxException
如果正则表达式语法不正确,则抛出。
让我们来看看 Java Regex 示例程序。
package com.journaldev.util;
import java.util.regex.*;
public class PatternExample {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".xx.");
Matcher matcher = pattern.matcher("MxxY");
System.out.println("Input String matches regex - "+matcher.matches());
// bad regular expression
pattern = Pattern.compile("*xx*");
}
}
当我们运行这个 java regex 示例程序时,我们得到以下输出。
Input String matches regex - true
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*xx*
^
at java.util.regex.Pattern.error(Pattern.java:1924)
at java.util.regex.Pattern.sequence(Pattern.java:2090)
at java.util.regex.Pattern.expr(Pattern.java:1964)
at java.util.regex.Pattern.compile(Pattern.java:1665)
at java.util.regex.Pattern.(Pattern.java:1337)
at java.util.regex.Pattern.compile(Pattern.java:1022)
at com.journaldev.util.PatternExample.main(PatternExample.java:13)
由于 Java 正则表达式围绕 String 展开,因此 Java 1.4 中扩展了 String 类以提供进行matches
正则表达式模式匹配的方法。它在内部使用Pattern
和Matcher
java regex 类来进行处理,但显然它减少了代码行。
Pattern
类还包含matches
将正则表达式和输入字符串作为参数并在匹配它们后返回布尔结果的方法。
所以下面的代码可以很好地匹配输入字符串与 Java 中的正则表达式。
String str = "bbb";
System.out.println("Using String matches method: "+str.matches(".bb"));
System.out.println("Using Pattern matches method: "+Pattern.matches(".bb", str));
因此,如果您的要求只是检查输入字符串是否与模式匹配,您应该使用简单的字符串匹配方法来节省时间和代码行。
只有在需要操作输入字符串或需要重用模式时,才应该使用 Pattern 和 Matches 类。
请注意,正则表达式定义的模式从左到右应用于字符串,一旦在匹配中使用源字符,就不能重复使用。
例如,正则表达式“121”将只匹配“31212142121”两次“_121____121”。
Java中的正则表达式——常见的匹配符号
单个字符的匹配规则如下:
多个字符的匹配规则如下:
复杂匹配规则主要有:
常用正则表达式校验规则:
一.校验数字的表达式
1.数字:^[0-9]*$
2.n位的数字:^\d{n}$
3.至少n位的数字:^\d{n,}$
4.m-n位的数字:^\d{m,n}$
5.零和非零开头的数字:^(0|[1-9][0-9]*)$
6.非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7.带1-2位小数的正数或负数:^(-)?\d+(.\d{1,2})?$
8.正数、负数、和小数:^(-|+)?\d+(.\d+)?$
9.有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10.有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11.非零的正整数:^[1-9]\d$ 或 ^([1-9][0-9]){1,3}$ 或 ^+?[1-9][0-9]*$
12.非零的负整数:^-[1-9][]0-9"$ 或 ^-[1-9]\d$
13.非负整数:^\d+$ 或 ^[1-9]\d*|0$
14.非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15.非负浮点数:^\d+(.\d+)?$ 或 ^[1-9]\d.\d|0.\d[1-9]\d|0?.0+|0$
16.非正浮点数:^((-\d+(.\d+)?)|(0+(.0+)?))$ 或 ^(-([1-9]\d.\d|0.\d[1-9]\d))|0?.0+|0$
17.正浮点数:^[1-9]\d.\d|0.\d[1-9]\d$ 或 ^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$
18.负浮点数:^-([1-9]\d.\d|0.\d[1-9]\d)$ 或 ^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$
19.浮点数:^(-?\d+)(.\d+)?$ 或 ^-?([1-9]\d.\d|0.\d[1-9]\d|0?.0+|0)$
二.校验字符的表达式
1.汉字:^[\u4e00-\u9fa5]{0,}$
2.英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3.长度为3-20的所有字符:^.{3,20}$
4.由26个英文字母组成的字符串:^[A-Za-z]+$
5.由26个大写英文字母组成的字符串:^[A-Z]+$
6.由26个小写英文字母组成的字符串:^[a-z]+$
7.由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8.由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
9.中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10.中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11.可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
12.禁止输入含有~的字符:[^~\x22]+
三.特殊需求的表达式:
1.Email地址:
^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$
2.域名:
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3.网址(url):
[a-zA-z]+://[^\s] 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=])?$
4.手机号码:
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
5.电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):
^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6.国内电话号码(0511-4405222、021-87888822):
\d{3}-\d{8}|\d{4}-\d{7}
7.身份证号身份证号(15位、18位数字):
^\d{15}|\d{18}$
8 短身份证号码(数字、字母x结尾):
^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10.密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
^[a-zA-Z]\w{5,17}$
\11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):
^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$
12.日期格式:
^\d{4}-\d{1,2}-\d{1,2}
\13. 一年的12个月(01~09和1~12):
^(0?[1-9]|1[0-2])$
14.一个月的31天(01~09和1~31):
15.钱的输入格式:
有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":
^[1-9][0-9]*$
16.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:
^(0|[1-9][0-9]*)$
17.首尾空白字符的正则表达式(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式):
^\s|\s$或(^\s)|(\s$)
18.腾讯QQ号:
[1-9][0-9]{4,} (腾讯QQ号从10000开始)
19.中国邮政编码:
[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
20.IP地址:
\d+.\d+.\d+.\d+ (提取IP地址时有用)
\21. IP地址:
((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))
Java 正则表达式元字符
我们在 Java 正则表达式中有一些元字符,就像常见匹配模式的短代码。
正则表达式 | 描述 |
---|---|
\d | 任何数字,除了 [0-9] |
\D | 任何非数字,[^0-9] 的缩写 |
\s | 任何空白字符,[\t\n\x0B\f\r] 的缩写 |
\S | 任何非空白字符,[^\s] 的缩写 |
\w | 任何单词字符,[a-zA-Z_0-9] 的缩写 |
\W | 任何非单词字符,[^\w] 的缩写 |
\b | 一个词的边界 |
\B | 非词边界 |
有两种方法可以将元字符用作正则表达式中的普通字符。
- 在元字符前面加上反斜杠 ()。
- 将元字符保持在 \Q(开始引用)和 \E(结束引用)内。
Java 中的正则表达式——量词
Java Regex Quantifiers 指定要匹配的字符出现的次数。
正则表达式 | 描述 |
---|---|
X? | x 出现一次或根本不出现 |
X* | X 出现零次或多次 |
X+ | X 出现一次或多次 |
X{n} | X 恰好出现 n 次 |
X{n,} | X 出现 n 次或更多次 |
X{n,m} | X 出现至少 n 次但不超过 m 次 |
Java Regex Quantifiers 也可用于字符类和捕获组。
例如,[abc]+ 表示 – a、b 或 c – 一次或多次。
(abc)+ 表示多一次“abc”组。我们现在将讨论匹配组(Capturing Groups)。
Java 中的正则表达式——匹配组
Java 捕获组中的正则表达式用于将多个字符视为一个单元。您可以使用()
. 与捕获组匹配的输入字符串部分保存到内存中,可以使用Backreference 调用。
您可以使用matcher.groupCount
method 找出 Java 正则表达式模式中捕获组的数量。例如, ((a)(bc)) 包含 3 个捕获组 – ((a)(bc)), (a) 和 (bc) 。
您可以在正则表达式中使用Backreference加上反斜杠 (),然后是要调用的组的编号。
捕获组和反向引用可能会令人困惑,所以让我们通过一个例子来理解这一点。
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false
在第一个示例中,在运行时第一个捕获组是 (\w\d),当与输入字符串“a2a2”匹配并保存在内存中时,它的计算结果为“a2”。所以\1 指的是“a2”,因此它返回true。由于同样的原因,第二个语句打印错误。
尝试自己理解语句 3 和 4 的这种情况。🙂
现在我们来看看 Pattern 和 Matcher 类的一些重要方法。
- 我们可以创建一个带有标志的 Pattern 对象。例如,
Pattern.CASE_INSENSITIVE
启用不区分大小写的匹配。 - Pattern 类还提供
split(String)
了类似于 String 类split()
方法的方法。 - 模式类
toString()
方法返回编译此模式的正则表达式字符串。 - Matcher 类具有
start()
和end()
index 方法,可以精确显示在输入字符串中找到匹配项的位置。 - Matcher 类还提供了 String 操作方法
replaceAll(String replacement)
和replaceFirst(String replacement)
.
让我们在一个简单的示例程序中看看这些 java 正则表达式方法。
package com.journaldev.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExamples {
public static void main(String[] args) {
// using pattern with flags
Pattern pattern = Pattern.compile("ab", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("ABcabdAb");
// using Matcher find(), group(), start() and end() methods
while (matcher.find()) {
System.out.println("Found the text \"" + matcher.group()
+ "\" starting at " + matcher.start()
+ " index and ending at index " + matcher.end());
}
// using Pattern split() method
pattern = Pattern.compile("\\W");
String[] words = pattern.split("one@two#three:four$five");
for (String s : words) {
System.out.println("Split using Pattern.split(): " + s);
}
// using Matcher.replaceFirst() and replaceAll() methods
pattern = Pattern.compile("1*2");
matcher = pattern.matcher("11234512678");
System.out.println("Using replaceAll: " + matcher.replaceAll("_"));
System.out.println("Using replaceFirst: " + matcher.replaceFirst("_"));
}
}
上面的java正则表达式示例程序的输出是。
Found the text "AB" starting at 0 index and ending at index 2
Found the text "ab" starting at 3 index and ending at index 5
Found the text "Ab" starting at 6 index and ending at index 8
Split using Pattern.split(): one
Split using Pattern.split(): two
Split using Pattern.split(): three
Split using Pattern.split(): four
Split using Pattern.split(): five
Using replaceAll: _345_678
Using replaceFirst: _34512678
这就是 Java 中正则表达式的全部内容。Java Regex 起初似乎很难,但如果您使用它们一段时间,它很容易学习和使用。