一.意义
(1)正则表达式:符合一定规则的表达式
(2)特点:用一些特别的符号表示一系列代码的操作,方便观看
(3)好处:可以简化对字符串的操作
(4)弊端:符号定义越多,正则越长,阅读性越差
二.正则的四种常见操作
1.匹配
boolean | matches(String regex) 告知此字符串是否匹配给定的正则表达式。 |
1.1 字符类
[abc] | 表示字符串当中某一位出现的字符。单单只有这个表示字符串第一位字符必须是abc,并且字符串正度为1 |
[^abc] | 任何字符,除了 a、b 或 c(否定),长度为1 |
[a-zA-Z] | a 到 z 或 A 到 Z,两头的字母包括在内(范围),长度为1 |
[a-d[m-p]] | a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z&&[def]] | d、e 或 f(交集) |
[a-z&&[^bc]] | a 到 z,除了 b 和 c:[ad-z](减去) |
[a-z&&[^m-p]] | a 到 z,而非 m 到 p:[a-lq-z](减去) |
1.2 预定义字符类
. | 任何字符(与行结束符可能匹配也可能不匹配) |
\d | 数字:[0-9](注意:因为"\d"是一个整体,d不能被转义。所以使用时要写成"\\d"才可以,以下同) |
\D | 非数字: [^0-9] |
\s | 空白字符:[ \t\n\x0B\f\r] |
\S | 非空白字符:[^\s] |
\w | 单词字符:[a-zA-Z_0-9] |
\W | 非单词字符:[^\w] |
1.3 Greedy数量词
X? | X,一次或一次也没有(X代表正则字符串regex) |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X{n} | X,恰好 n 次 |
X{n,} | X,至少 n 次 |
X{n,m} | X,至少 n 次,但是不超过 m 次 |
1.4 边界匹配器
^ | 行的开头(要在每一行中找东西时,可以写行开头,行结尾) |
$ | 行的结尾 |
\b | 单词边界(要在每个单词中查找东西,可以写单词边界) |
\B | 非单词边界 |
\A | 输入的开头 |
\G | 上一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
\z | 输入的结尾 |
2.切割
String[] | split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
(1)"l i w ang wu zhaoliu"==>如何取出所有字符?可定义正则为:” +“即可取出所有字符存入数组中
(2)”a.b.c“==>如何切句号?可以定义正则为:”\\.“(因为句号在正则中有表示,需转义)
(3)”gajaaskkglkzzajeegk“==>按照叠词进行切割?可以定义正则为:”(.)\\1”(切割叠词:把叠词去掉,分割字符串)
2.1 重点:分组
把要重复用到的部分用小括号括起来,如(之后要用到的元素),而且组有自动的编号,从1开始。后边要用到这个组的内容,通过"\1"的形式引用该组,不过写到regex中要写作"\\1"
3.替换
String | replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
(1)”gajaaaaaskkllglkzzzajeegk“==>将叠词替换为单个字符?可以定义正则为:"(.)\\1+",定义替换的字符串为:“$1”(“$1”表示的前边正则得到的第一组)
4.获取
4.1 过程
(1)将正则表达式封装成对象
(2)将正则对象与要操作的字符串相关联
(3)关联后,获取正则匹配引擎
(4)通过引擎对符合规则的子串进行操作
4.2 Pattern类
方法摘要 | |
---|---|
static Pattern | compile(String regex) 将给定的正则表达式编译到模式中。(将正则封装为对象,因为获取是一个复杂的操作) |
Matcher | matcher(CharSequence input) 创建匹配给定输入与此模式的匹配器。(将我们的正则对象与作用的字符串相关联,获取匹配器对象) |
4.3 Matcher类
方法摘要 | |
---|---|
boolean | matches() 尝试将整个区域与模式匹配。(String类中matches()方法就是调用的这个方法) |
String | replaceAll(String replacement) 替换模式与给定替换字符串相匹配的输入序列的每个子序列。(String类中replaceAll()方法就是调用的这个方法) |
boolean | find() 尝试查找与该模式匹配的输入序列的下一个子序列。(find()方法类似迭代器hasNext()方法,find()方法与matches()使用的同一个指针) |
String | group() 返回由以前匹配操作所匹配的输入子序列。(group()方法类似迭代器的next()方法) |
int | start() 返回以前匹配的初始索引。(返回匹配区域的字符串首字符索引) |
int | end() 返回最后匹配字符之后的偏移量。(返回匹配区域的字符串尾字符索引) |
三.正则使用示例代码
package cn.doing.pattern;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class Test1 {
@Test
public void practice1(){
String str = "abc3";
String regex = "[a-z]{3}\\d";
System.out.println(str.matches(regex));
}
//去掉点和把叠词变为单个字
@Test
public void practice2(){
String str = "黄黄黄黄.....镇镇镇.......王王..逊逊逊逊.....于于于于...泽泽泽";
//String regex = "\\.";
str = str.replaceAll("\\.+", "");
System.out.println(str);
str = str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
}
//分开IP地址并且进行排序
@Test
public void practice3(){
String str = "192.168.0.38 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";
str = str.replaceAll("(\\d+)","00$1");
str = str.replaceAll("0*(\\d{3})","$1");
TreeSet<String> ts = new TreeSet<String>();
String[] arr = str.split(" ");
for(String s : arr){
System.out.println(s);
ts.add(s);
}
System.out.println();
for(String s : ts){
System.out.println(s.replaceAll("0+(\\d+)","$1"));
}
Pattern p = Pattern.compile("\\.");
Matcher m = p.matcher(str);
}
//矫正邮件地址
@Test
public void practice4(){
String str = "mengqidlufei8932@sina.com.cn.asd.cn";
String regex = "[a-zA-Z0-9_]+@\\w+(\\.\\w+)+";
System.out.println(str.matches(regex));
}
}