目录
一、正则表达式的介绍
正则表达式是对字符串操作的逻辑表达式,说的是不是有点抽象呢,那说说它的作用其实更加好懂。正则表达式可以校验字符串是否符合规则(规则由你定),这样的话你就可以在一段文本内容中查找你想要的内容了
二、正则表达式的基本语法
上面说过了正则表达式其实就是对于一个字符串根据你制定的规则做出的一个逻辑判断,所以我们会使用其中的一个API,也就是matches函数,参数是你制定的规则,返回值是boolean型。即字符串.matches(规则)
(1)字符类
[abc] 只能是abc其中一个字符 [^abc] abc这三个字符不可以被选择,其他字符可以 [a-zA-Z] 只能在a-z和A-Z这两个区间中选择,两个区间以外的字符不可被选 [a-z[A-Z]] 和第三种的意思是一样的,只能在两个区间中被选择 [a-z&&[def]] a-z和def的交集,也就是说只能取def这三个字符其中之一 [a-z&&[^def]] a-z中并且出了def的字符 [a-z&&[^m-p]] a-z中除了m-p的字符,也就是[a-lq-z]
(2)预定义符
. 任意字符 \d 一个数字[0-9] \D 非数字[^0-9] \s 一个空白字符[\t\n\f\r] \S 非空白字符 \w [a-zA-Z_0-9]英文数字下划线 \W 除了英文数字下划线
(3)数量词
x? x出现了一次或者是0次 x+ x出现了一次或者多次 x* x出现了0次或者是多次 x{n} x出现了正好是n次 x{n,} x出现了至少n次 x{n,m} x出现了至少是n次但是不超过m次
这里我提醒大家一下,千万要看清楚你写的规则是匹配一个字符还是多个字符
三、正则表达式的具体实例
(1)判断电话号码是否符合规则
需求:十一个数字,第一个数字只能是1,最后一个数字不能是0。
public class Test { public static void main(String[] args){ Scanner sca=new Scanner(System.in); System.out.print("请输入你的电话号码:"); String s=sca.next();//电话号码 String rule="1[0-9]{9}[1-9]";//定义的规则 System.out.print(s.matches(rule)); } }
(2)简单爬虫
需求:一段文本中查找Java或者是Java出现的版本号
public class Test { public static void main(String[] args){ String s="市东南部ujbis1Java12史努比偶数" + "圣诞节你为奶茶店搜防静电Java1山东噢in计算Jav为oio看上你" + "Java19是可能空岛生存·Java30搜坚定Java=数据库你打算"; String regex="Java\\d{0,2}"; Pattern p= Pattern.compile(regex); Matcher m=p.matcher(s); while(m.find()){ System.out.println(m.group()); } } }
(3)爬取电话和邮箱
需求:在一段文本中,爬取电话号码和邮箱
public class Test { public static void main(String[] args){ String s="81是的配送费打开你发182654678541所点击时间内" + "ujhgtr@163.com搜的金丝楠18871110981是啊都是你的手机卡圣诞节迫使@163.com" + "搜坚定yuhsyw@163.coomi1搜电脑172890987665搜绝对是gygwas163.com庶竭驽钝" + "18235454567是第几行你UIUIu@163.com我似乎单词表18765432140"; String re1="1\\d{9}[1-9]";//电话号码 String re2="[a-zA-Z]{6}@163.com"; String re=re1+"|"+re2;//两个规则满足其中之一即可,用竖线 Pattern p=Pattern.compile(re); Matcher m=p.matcher(s); while(m.find()){ System.out.println(m.group()); } } }
(4)条件爬取
((?i)java) 忽略Java的大小写 (java)(?=7|8) 这里的问号其实可以理解成占位符,总体表达的意思是查找java7或者java8并且输出时 不显示java后面的的版本号 (java)(?:7|8) 与上面相反,它是显示后面的版本号的 (java)(?!7|8) 查找除了java7和java8
需求:在一段文本中查找Java和Java17,Java8,Java7(忽略大小写)
public class Test { public static void main(String[] args){ String s="是的苏北jaVa18是可能都跑了实力派我JaVA89osadisd我的是极品搜" + "JAVA17isadhoJAVA11安排激动java10时都是你我说的菜农Java12是哦滑动SOL" + "是冬季是破烦巴萨jAvA8开始就等你"; String re1="((?i)java)(?=8|7|17)";//查找只输出前面的java部分 String re2="((?i)java)(?:7|8|17)";//查找同时也输出后面的部分,也可以写成((?i)java)(7|18|17) String re3="((?i)java)(?!7|8|17)";//查找除了版本号是8,7,,17 System.out.println("规则1"); Pattern p1=Pattern.compile(re1); Matcher m1=p1.matcher(s); while(m1.find()){ System.out.println(m1.group()); } System.out.println("规则2"); Pattern p2=Pattern.compile(re2); Matcher m2=p2.matcher(s); while(m2.find()){ System.out.println(m2.group()); } System.out.println("规则3"); Pattern p3=Pattern.compile(re3); Matcher m3=p3.matcher(s); while(m3.find()){ System.out.println(m3.group()); } } }
(5)贪婪和非贪婪爬取
贪婪爬取:在爬取数据的时候尽可能的多获取数据 非贪婪爬取:在爬取数据的时候尽可能少获取数 据 只写+,*表示贪婪爬取(Java中默认是贪婪爬取) +?,+*表示非贪婪爬取
public class Test { public static void main(String[] args){ String s="搜绝对是你uiuisudjh怕端口abbbbb啥动静那等"; String rex1="ab+"; String rex2="ab?+"; Pattern p1=Pattern.compile(rex1); Pattern p2=Pattern.compile(rex2); Matcher m1=p1.matcher(s); Matcher m2=p2.matcher(s); System.out.println("贪婪爬取"); while(m1.find()){ System.out.println(m1.group()); } System.out.println("非贪婪爬取"); while(m2.find()){ System.out.println(m2.group()); } } }
(6)正则表达式在字符串表达式中的使用
这里主要介绍两个方法:replaceAll和split replaceAll(规则,代替的字符串) 将字符串中符合规则的字符串替换成代替的字符串,返回值是修改后的 字符串,原来的字符串时不会发生变化的 split(规则) 根据规则切割,返回值是字符串数组
public class Test { public static void main(String[] args){ String s="李三sodjsodjso张三丰0osodndn王天霸"; String ss=s.replaceAll("[a-zA-Z0-9]+","vs"); System.out.println(ss); String[] sc=s.split("[0-9a-zA-Z]+"); System.out.println("字符串数组:"); for(int i=0;i<sc.length;i++){ System.out.println(sc[i]); } } }