正则表达式和其在Java中的运用
在线测试工具:
简介:
是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串,抓重点:正则表达式是一个特殊的字符串。其实就是一种规则。个人感觉和C语言中的printf函数中的格式字符串有点类似。
正则表达式规范:
- 单个字符类:
以下字符串代表匹配的都是单个字符
- [abc] a,b,c中的任意一个字符
- [^abc] 除了a,b,c以外的任意一个字符
- [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
- [a-d[m-p]] a 到 d 或 m 到 p (两个的并集)
- [a-z&&[def]] a 到 z 或 d,e,f(依然并集)
- [a-z&&[^bc]] a 到 z,除了b 和 c:[ad-z] (相当于前后两个范围相减)
- [a-z&&[^m-p]] a 到 z,而非m到p: [a-lq-z] (依然是减去)
- [a|z] 匹配a或z,和[az]一样
- 转义字符(预定义字符)
注意:在其他语言中,\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。
在 Java 中,\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
- \d 数字:[0-9]
- \D 非数字: [^0-9]
- \s 空白字符: [\t\n\x0B\f\r]
- \S 非空白字符:[^\s]
- \w 单词字符:[a-zA-z_0-9]
- \W 非单词字符:[^\w]
- \b 匹配单词边界
- 数量词:(即字符出现的次数)
- X? X出现了一次 或者 一次字符也没有出现(此处不是指X出现了0次,而是整个字符串没有内容)
- X* X出现了零次到多次
- X+ X出现了一次到多次
- X{n} X出现了恰好n次
- X{n,} X至少出现了n次
- X{n,m} X出现了n次到m次
- 正则表达式的分组功能(捕获组)(捕获组是把多个字符当一个单独单元进行处理的方法, 它通过对括号内的字符分组来创建):
在正则表达式中还提供了一种将表达式分组的机制,当使用分组时,除了获得整个匹配。 还能够在匹配中选择每一个分组。
比如(ab),就以ab为一组来匹配,“a (cat|dog)” 就可以用来匹配"a cat"或者"a dog";
正则表达式的进阶:
贪婪匹配和懒惰匹配
正则表达式在匹配时默认的是贪婪匹配的模式,即匹配尽可能多的字符,例如:
正则式为"<.+>"的情况下,下列文本:
<span><b>This is a sample text</b></span>
将会被全部匹配,而这显然与我们的本意,即只匹配四个尖括号的内容相违背
修改方法为将正则式改为"<.+?>",这样就会使用懒惰匹配模式,即匹配尽可能少的字 符
分组捕获相关
- 在正则表达式中还提供了一种将表达式分组的机制,当使用分组时,除了获得整个匹配。还能够在匹配中选择每一个分组。
- 要实现分组很简单,使用()即可。
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。 - 非捕获元:
用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用。
其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向先行断言,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,负向先行断言,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
1.例如,如果想捕获形如aabb的字符,可以使用反向引用,即:
String regx = "(.)\\1(.)\\2" ;
\\1代表第一个分组,\\2代表第二个分组
代表第一个字符出现两次后,第二个字符也出现两次
- 正向先行断言:?=
即匹配右边有指定串的字符串
正向先行断言和负向先行断言相反 - 负向先行断言:?!
即匹配右边没有指定串的字符串
我们可以创建否定先行断言模式的匹配,即某个字符串后面不包含另一个字符串的匹配模式。
否定先行断言模式通过 (?!pattern) 定义。比如,我们匹配后面不是跟着 “b” 的 “a”:
a(?!b)
定位符
- ^ 开头,匹配字符串开头,或者当使用多行标志(m)时,匹配一行的开头
- $ 结尾, 匹配字符串结尾, 或者当使用多行标志(m)时,匹配一行的结尾
- 注意:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。
若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。
Java中的模式与匹配
Java中的正则机制在包 java.util.regex中
java.util.regex 包主要包括以下两个类和一个异常:
- Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。 - Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。 - PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
一般运用时我们遵循以下步骤:
第一步,通过正则表达式创建模式对象 Pattern。
第二步,通过模式对象 Pattern,根据指定字符串创建匹配对象 Matcher。
第三步,通过匹配对象 Matcher,根据正则表达式操作字符串。
由于Pattern类和Matcher类的构造方法都被私有了,我们想要获得相关实例就需要调用相应的静态方法
- 比如如果想提取出一段字符中的电话号码:
public class ParrtenAndMacher {
public static void main(String[] args) {
String one = "我的号码15555555555,以前号码15555555566";//被匹配的串
String regx = "1[3579]\\d{9}";//规定的正则式
Pattern p = Pattern.compile(regx);//根据正则式创建模式
Matcher m = p.matcher(one);//根据模式和被匹配字符串创建匹配器
boolean b1 = m.find();//用匹配器去匹配字符,必须先找
System.out.println(b1);
String s1 = m.group();//被匹配到的第一组
System.out.println(s1);
m.find();//内部指针后移
System.out.println(m.group());//被匹配到的第二组
}
}