一、正则表达式
1.1、概述
符合一规则的表达式:用于专门操作字符串。
正则表达式则必须依靠Pattern类与Matcher类,这两个类都在java.util.regex包中定义。Pattern类的主要作用是进行正则规范的编写,而Matcher类主要是执行规范,验证一个字符串是否符合其规范。
Pattern:
正则表达式的编译表示形式。
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 对象,依照正则表达式,该对象可以与任意匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches();
Matcher:
通过解释 对 执行匹配操作的引擎。
通过调用模式的 方法从模式创建匹配器。创建匹配器后,可以使用它执行三种不同的匹配操作:
-
方法尝试将整个输入序列与该模式匹配。
-
尝试将输入序列从头开始与该模式匹配。
-
方法扫描输入序列以查找与该模式匹配的下一个子序列。
每个方法都返回一个表示成功或失败的布尔值。通过查询匹配器的状态可以获取关于成功匹配的更多信息。
二、正则规则-预定义字符类
2.1、规则-预定义字符类
常用正则规则
No. | 规范 | 描述 | No. | 规范 | 描述 |
1 | \\ | 表示反斜线(\)字符 | 2 | \t | 表示制表符 |
3 | \n | 表示换行 | 4 | [abc] | 字符a、b或c |
5 | [^abc] | 除了a、b、c之外的任意字符 | 6 | [a-zA-Z0-9] | 表示由字母、数字组成 |
7 | \d | 表示数字0-9 | 8 | \D | 表示非数字[^0-9] |
9 | \w | 表示字母、数字、下划线 | 10 | \W | 表示非字母、数字、下划线[^\w] |
11 | \s | 表示所有空白字符(换行、空格等) | 12 | \S | 表示所有非空白字符 [^\s] |
13 | ^ | 行的开头 | 14 | $ | 行的结尾 |
15 | . | 匹配除换行符之外的任意字符 |
|
|
|
2.2、匹配规则
数量表示(X表示一组规范)
No. | 规范 | 描述 | No. | 规范 | 描述 |
1 | X | 必须出现一次 | 2 | X? | 可以出现0次或1次 |
3 | X* | 可以出现0次、1次或多次 | 4 | X+ | 可以出现1次或多次 |
5 | X{n} | 必须出现n次 | 6 | X{n,} | 必须出现n次以上 |
7 | X{n,m} | 必须出现n~m次 |
|
|
|
逻辑运算符(X、Y表示一组规范)
No. | 规范 | 描述 | No. | 规范 | 描述 |
1 | XY | X规范后跟着Y规范 | 2 | X | Y | X规范或Y规范 |
3 | (X) | 做为一个捕获组规范 |
|
|
|
2.3、Pattern类的常用方法
No. | 方法 | 类型 | 描述 |
1 | public static Pattern compile(String regex) | 普通 | 指定正则表达式规则 |
2 | public Matcher matcher(CharSequence input) | 普通 | 返回Matcher类实例 |
3 | public String[] split(CharSequence input) | 普通 | 字符串拆分 |
在Pattern类中如果要想取得Pattern类实例,则必须调用compile()方法。
2.4、Pattern常用方法
方法摘要 | |
---|---|
static | ( regex) 将给定的正则表达式编译到模式中。 |
static | ( regex, int flags) 将给定的正则表达式编译到具有给定标志的模式中。 |
int | () 返回此模式的匹配标志。 |
| ( input) 创建匹配给定输入与此模式的匹配器。 |
static boolean | ( regex, input) 编译给定正则表达式并尝试将给定输入与其匹配。 |
| () 返回在其中编译过此模式的正则表达式。 |
static | ( s) 返回指定 String 的字面值模式 String 。 |
[] | ( input) 围绕此模式的匹配拆分给定输入序列。 |
[] | ( input, int limit) 围绕此模式的匹配拆分给定输入序列。 |
| () 返回此模式的字符串表示形式。 |
2.5、边界匹配器
边界匹配器 | |
---|---|
^ | 行的开头 |
$ | 行的结尾 |
\b | 单词边界 |
\B | 非单词边界 |
\A | 输入的开头 |
\G | 上一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
\z | 输入的结尾 |
三、String对正则表达式的支持
3.1、常用方法
Matcher类的常用方法在
No. | 方法 | 类型 | 描述 |
1 | public boolean matches(String regex) | 普通 | 字符串匹配 |
2 | public String replaceAll(String regex,String replacement) | 普通 | 字符串替换 |
3 | public String[] split(String regex) | 普通 | 字符串拆分 |
四、示例
4.1、验证用户输入不是QQ号
/*验证用户输入不是QQ号QQ号以1-9开头,5-15位长度都是数字使用\d或者[0-9]表示数字完成*/import java.util.*;import java.util.regex.*;class RegexDemo1{ public static void main(String[] args) { //声明一个扫描器的变量,来接收用户键盘输入 Scanner input=new Scanner(System.in); //接收输入数据 String qq=input.nextLine(); //调用校验 checkQQ(qq); } /* 校验QQ */ public static void checkQQ(String qq) { //定义正则 //String regex="^[1-9]\\d{4,14}$"; String regex="[1-9][0-9]{4,14}"; //获取Pattern对象 Pattern p=Pattern.compile(regex); //验证字符串内容是否符合正则 Matcher m=p.matcher(qq); //判断 if(m.matches()) { System.out.println(qq+"是合法的QQ!"); } else { System.out.println(qq+"不是合法的QQ!"); } }}
4.2、验证手机号码是不是正确
/*验证手机号码是不是正确手机号1开头,都是数字,长度11位*/import java.util.regex.*;import java.util.*;class RegexDemo2 { public static void main(String[] args) { Scanner input=new Scanner(System.in); String mobile=input.nextLine(); checkMobile(mobile); } public static void checkMobile(String mobile) { //String regex="1[0-9]{10}"; String regex="^[1][0-9]{10}$"; Pattern p=Pattern.compile(regex); Matcher m=p.matcher(mobile); if(m.find()) { System.out.println(mobile+"是合法的手机号码!"); } else { System.out.println(mobile+"不是合法的手机号码!"); } }}
4.3、验证用户输入邮箱是否合法
/*验证用户输入邮箱是否合法*/import java.util.regex.*;import java.util.*;class RegexMail { public static void main(String[] args) { Scanner input =new Scanner(System.in); String email=input.nextLine(); checkMail(email); } public static void checkMail(String email) { //邮件正则 String regex="\\w+@\\w+(\\.\\w+)+"; //直接使用String类的方法来比较 boolean flag=email.matches(regex); //输出结果 System.out.println(email+"..."+flag); }}
4.4、字符串匹配
/*字符串匹配*/import java.util.regex.*;class RegextDemo3 { public static void main(String[] args) { String str="aoob"; String reg="ao?b"; boolean b=str.matches(reg);//false ?表示不出现或者最多只能出现一次 System.out.println(str+"......"+b); reg="ao+b";//o最少出现一次,可出现多次 b=str.matches(reg); System.out.println(str+"......"+b);//true str="ab"; reg="ao+b";//o必须最少出现一次, b=str.matches(reg); System.out.println(str+"......"+b);//false str="ab"; reg="ao*b";//可以不出现也可以出现多次 b=str.matches(reg); System.out.println(str+"......"+b);//true str="aooooooob"; reg="ao{4,}b";//o最少出现4次,可以更多次 b=str.matches(reg); System.out.println(str+"......"+b);//true reg="ao{4,6}b}";//o现象4-6次 b=str.matches(reg);//o出现了7次 System.out.println(str+"......"+b);//false }}
4.5、字符串切割
/*切割*/import java.util.regex.*;class RegexDemo2 { public static void main(String[] args) { split_Fun(); System.out.println("================"); split_Fun2(); System.out.println("================"); split_Fun3(); System.out.println("================"); split_Fun4(); System.out.println("================"); split_Fun5(); } /* 按空格切割 */ public static void split_Fun() { String str="zhangsan lisi wangwu zhaoliu"; String reg="\\s+";//\s表示空白字符也可以" +"表示 String [] arr=str.split(reg); //长度 System.out.println("长度"+arr.length); for(String s:arr) { System.out.println(s); } } /* 按一个元素多次重复出现切割 */ public static void split_Fun2() { String str="zhangsan.lisi..wangwu...zhaoliu"; String reg="\\.+"; String [] arr=str.split(reg); //长度 System.out.println("长度"+arr.length); for(String s:arr) { System.out.println(s); } } /* 双反斜杠\\\\ */ public static void split_Fun3() { String str="c:\\abc\\a.txt"; String reg="\\\\+"; String [] arr=str.split(reg); //长度 System.out.println("长度"+arr.length); for(String s:arr) { System.out.println(s); } } /* 按照叠词来切割 为了可以让规则被重用可以将规则封装为一个组 用()完成,组的出现都有编号 从1开始,想要使用已经有的组可以通过\n的形式来获取 n就是组的编号 */ public static void split_Fun4() { String str="erkktyqquioppdffyphhct"; //按照叠词来切割 String reg="(.)\\1"; //(.)表示组,\1捕获组, String [] arr=str.split(reg); //长度 System.out.println("长度"+arr.length); for(String s:arr) { System.out.println(s); } } /* 按重复元素切割 */ public static void split_Fun5() { String str="helloaaworkldbbbuiopccc"; //按照叠词来切割 String reg="(.)\\1+"; //(.)表示组,\1捕获组, String [] arr=str.split(reg); //长度 System.out.println("长度"+arr.length); for(String s:arr) { System.out.println(s); } } }
4.6、替换
/*正则替换*/import java.util.regex.*;class ReplaceAllDemo { public static void main(String[] args) { //字符串中的数字替换为#号 String str="wer123ty343232uio23232f889..ffdsaf4324qq"; String reg="\\d{4,}"; //4个以上的数字替换 replaceAll_Fun(str,reg,"#"); System.out.println("================="); String str1="erkktyqqquizzzzzzofffpeeenmcvvhss"; //将叠替换为$号 String reg1="(.)\\1+"; replaceAll_Fun(str1,reg1,"\\$"); System.out.println("================="); String str2="erkktyqqquizzzzzzofffpeeenmcvvhss"; //将叠替换为单个字符 String reg2="(.)\\1+"; replaceAll_Fun(str2,reg2,"$1"); //使用$获取组的内容 } public static void replaceAll_Fun(String str,String reg,String newStr) { //替换 str=str.replaceAll(reg,newStr); System.out.println(str); }}
4.7、获取
/*获取:使用正则表达式将字符串符合规则的子串取邮1.将正则表达式封装成对象2.让正则对象和要操作的字符串相关联3.关联扣, 获取正则匹配引擎4.通过引擎对象符合规则的子串操作,比如取出*/import java.util.regex.*;class RegexDemo4 { public static void main(String[] args) { getDemo1(); System.out.println("==============="); } public static void getDemo1() { String str="ming tian jiu yao fang jia le , da jia. AWT HELLO"; String reg="\\b[A-Za-z]{3}\\b"; //按3个字母组成的单词获取\b表示单词边界 //将规则封装为对象 Pattern p=Pattern.compile(reg); Matcher m=p.matcher(str); //尝试查找与该模式匹配的输入序列的下一个子序列 while(m.find()) { //获取获取的组 System.out.println(m.group());//jiu yao jia jia System.out.println(m.start()+"...."+m.end()); } }}
4.8、示例
/*将下列字符串转成:学要学编程"我我...我我...我要...要要...学学学...学学...编编编...编程..程.程程...程...程";1.如果只想知道该字符是否符合规则--使用匹配2.想要将已经有的字符串变成另一个字符串,替换3.想要按照自定义方式,将字符串变成多个字符串,---切割-获取规则以外的字符串4.想要拿到符合要求的字符串子串,----获取---获取符合规则的子串*/import java.util.*;class RegexText { public static void main(String[] args) { String str="我我...我我...我要...要要...学学学...学学...编编编...编程..程.程程...程...程"; /* 替换 先将..去掉 再将重复的内容变成单个内容 */ str=str.replaceAll("\\.+","");//将.替换为""空字符串 System.out.println(str); str=str.replaceAll("(.)\\1+","$1");//使用组,替换 System.out.println(str); }}
4.9、替换,切割
/*192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30还按照字符串自然顺序,只要让它们每一段都 是3位即可。1.按照每一段需要的最多的0进行补齐,那么每一段就会至少保证3位2.将每一段只保留3位。这位的所有的IP地址都每一段3位*/import java.util.*;import java.util.regex.*;class RegexText2{ public static void main(String[] args) { String ip="192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30"; //为每一段数字前加2个0 ip=ip.replaceAll("(\\d+)","00$1"); System.out.println(ip); /*00192.00168.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030 */ //再次替换 ip=ip.replaceAll("0*(\\d{3})","$1"); System.out.println(ip); //192.168.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030 //切割 String [] arr=ip.split(" +"); /* Arrays.sort(arr); System.out.println(Arrays.toString(arr)); */ //或者使用TreeSet TreeSetts=new TreeSet (); for(String s:arr) { ts.add(s); } //遍历Set集合 for(String s:ts) { //将前置0删除 System.out.println(s.replaceAll("0*(\\d+)","$1")); } /* 2.2.2.2 8.109.90.30 10.10.10.10 102.49.23.13 192.168.1.254 */ }}
五、爬虫
5.1、示例
/*爬虫1从页面爬邮箱*/import java.io.*;import java.util.regex.*;import java.util.*;import java.net.*;class RegexTest1{ public static void main(String[] args) throws Exception { Listlist=getMail(); for(String s:list) { System.out.println(s); } } public static List getMail() throws Exception { //从指定网址http://www.hao123.com/ String uaddr="http://www.hao123.com/"; //转换为URL对象 URL url=new URL(uaddr); //获取URLConnection对象,并连接,再获取流 //openStream(),就是openConnection().getInputStream()是个字节流 //封装为字符缓冲流 BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream())); //邮箱正则 String reg="\\w+@\\w+(\\.\\w+)+"; //获取封装对象 Pattern p=Pattern.compile(reg); List list = new ArrayList (); //开始读取流 String line=null; while ((line=br.readLine())!=null) { //获取正则校验对象 Matcher m=p.matcher(line); //获取 while (m.find()) { //获取组,并添加 list.add(m.group()); } } br.close(); //返回结果集 return list; }}
示例
/*网页爬虫(蜘蛛)*/import java.io.*;import java.util.regex.*;class RegexTest3{ public static void main(String[] args) throws Exception { getMail(); } public static void getMail() throws Exception { BufferedReader br=new BufferedReader(new FileReader("d:\\mail.txt")); String mailReg="\\w+@\\w+(\\.\\w+)+"; Pattern p=Pattern.compile(mailReg); String line=null; while ((line=br.readLine())!=null) { Matcher m=p.matcher(line); while (m.find()) { System.out.println(m.group()); } } }}/*fdsfadsafdsfdsfsdf> abc@sina.comfdsfads@sina.com fdsaf@qq.com abc@sina.com abc@163.com abc@sina.com fdsafdsc@sina.com weweq@sina.com abc@sina.com adsdsafdsc@sina.com abc@sina.com abc@sina.com;fdslfdsfdsf;dsjfsdjfffdsfdsfadsafdsfdsfsdf> abc@sina.com abc@sina.com