黑马程序员--java基础之正则表达式
来源:互联网 发布:淘宝预热商品怎么删除 编辑:程序博客网 时间:2024/05/22 13:02
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
以前在公司上班的时候,因为工作上的需要,同事写了一个在网页上抓取数据的程序,然后放在公司的服务器,不停的运行,然后从别人的网站上抓取我们需要的数据,每隔3秒就访问一次网页,然后从新的网页上抓取数据。当时感觉很牛B,毕竟叫我弄,我是搞不定的,因为我不懂正则表达式。如今,咱也学习正则表达了,嘿嘿
咱们先来了解一下正则的知识
正则表达式:符合一定规则的表达式
作用:用于专门操作字符串
特点:用于一些特定的符号来表示一些代码操作。这样就简化书写。所以学习正则表达式,就是在学习一些特殊符号的使用。
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。
作用:用于专门操作字符串
特点:用于一些特定的符号来表示一些代码操作。这样就简化书写。所以学习正则表达式,就是在学习一些特殊符号的使用。
好处:可以简化对字符串的复杂操作。
弊端:符号定义越多,正则越长,阅读性越差。
以我们现阶段学习的知识来检验一个QQ号是否合格(不是以0开头,长度为5-15位的数字)
public static void checkQQ(){String qq="23414243";int len=qq.length();if(len>=5&&len<=15){if(!qq.startsWith("0")){char[] arr=qq.toCharArray();boolean flag=true;for(int x=0;x<arr.length;x++){if(!(arr[x]>='0' &&arr[x]<='9')){flag=false;break;}}if(flag){System.out.println("qq:"+qq);}else{System.out.println("qq号不符合规则");}}}}
用正则表达式如何做呢?
public static void method(){//不能以0开头,长度为5-15位的QQ号String str="1236465";String regex="[1-9]\\d{4,14}";boolean flag=str.matches(regex);System.out.println(flag);}
哇哦,屌爆了有没有!!!只有四句!!!哦,regex这个变量的值不懂?下面就来了。。。
再来看[1-9]\\d{4,14}:表示第一位是由1~9等数字组成。从第二位开始都是数字,而且数字的长度是4-14个,加上首位,长度就是5~15个了。。。
正则表达式具体操作功能
1、匹配 : String matches() 用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false
/*匹配手机号,11位手机号段只有13xxx 15xxx 18xxx*/public static void method_1(){String tel="18707122014";String telReg="1[358]\\d{9}";System.out.println(tel.matches(telReg));}
2、切割 String[] split(String regex)
class RegexDemo{public static void main(String[] args){//使用.切割(单独的.代表任意字符,所以要加上转义字符,而在字符串中要使用转义字符要再加上\)method_Split("zhangsan.lisi.wangwu.sunba","\\.");method_Split("c:\\abc\\a.txt","\\\\");/*为了可以让规则的结果被重用,可以将规则封装成一个组,用()完成。组的出现 都有编号,从1开始,想要使用已有的组,可以通过\n (n就是组的编号)的形式来获取*///按叠词切(其中的小括号里的表示一组,后面的1表示后面的和第一组内容一致,.代表任意字符)method_Split("sdkkaseqqtryyfkaacgh","(.)\\1");//按多个叠词切()method_Split("sdkkaseqqqqqtryyyyyyyyyfkaacgh","(.)\\1+");}public static void method_Split(String str,String regex){String[] arr=str.split(regex);for(String s:arr){System.out.println(s);}}public static void method_Split1(){String str="zhangsan lisi wangwu zhaoliu";//切割多个空格String regex=" +";String[] arr=str.split(regex);for(String s:arr){System.out.println(s);}}}
以前,当我们遇到一个字符串由多个字符串组成,中间用一个空格隔开的时候,我们往往会通过split(" ")将这个字符串切割成一个字符串数组,但是当中间隔开的不是一个空格,而是多个空格时,我们就会抓狂了。。。。但是现在,可以用一个空格加一个"+"来表示多个空格,同样可以完成切割。是不是很方便?
当用于分隔的不是空格,而是小数点的时候,就用小数点分隔,但是,小数点在这里表示的是任意字符,而我们仅仅想把它作为小数点用,所以就用到了转义字符,而在字符串中,表示转义字符要用两个\\来表示。如上例
若是用\\隔开的咋办?那就是\\\\
注:为了可以让规则的结果被重用,可以将规则封装成一个组,用()完成。组的出现 都有编号,从1开始,想要使用已有的组,可以通过\n (n就是组的编号)的形式来获取。
"(.)\\1" 这个代表的意思是,()中的是一个组,代表的是任意字符,而后面的\\1表示使用编号为1的组的结果,并在一起就是两个相同的任意字符,就是叠词,"(.)\\1+",这里多了个"+"表示多个叠词
3、替换 String replaceAll()
class RegexDemo{public static void main(String[] args){//将字符串中长度大于等于5的数字替换成#method_Replace("asfdf13845218652asdfgkf23345aff","\\d{5,}","#");//将字符串中的叠词替换成"&"method_Replace("sdkkaseqqqqqtryyyyyyyyyfkaacgh","(.)\\1+","&");//将字符串中的叠词替换成一个,如zzz-->z //通过$来获取前一个规则中的第一个组method_Replace("sdkkaseqqqqqtryyyyyyyyyfkaacgh","(.)\\1+","$1");}//替换public static void method_Replace(String str,String reg,String newstr){str=str.replaceAll(reg,newstr);System.out.println(str);}}
正则表达式的第四个功能
获取:将字符串中符合规则的子串取出
操作步骤:
1、将正则表达式封装成对象
2、让正则对象和要操作的字符相关联
3、关联后,获取正则匹配引擎
4、通过引擎对符合规则的子串进行操作。如取出
1、将正则表达式封装成对象
2、让正则对象和要操作的字符相关联
3、关联后,获取正则匹配引擎
4、通过引擎对符合规则的子串进行操作。如取出
上面的步骤中涉及到了两个类 Pattern和Matcher
Pattern:正则表达式的编译表示形式。
Matcher:通过解释 Pattern 对 character sequence 执行匹配操作的引擎。通过调用模式的 matcher 方法从模式创建匹配器。
Matcher:通过解释 Pattern 对 character sequence 执行匹配操作的引擎。通过调用模式的 matcher 方法从模式创建匹配器。
具体使用:
import java.util.regex.*;class RegexDemo2{public static void main(String[] args){getDemo();}public static void getDemo(){String str="ming tian jiu yao fang jia le ,da jia";System.out.println(str);/*其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。只不过被String的方法封装后,用起来较为简单。但是功能却单一。*///获取字符串中4个长度的单词//\b表示单词边际String reg="\\b[a-z]{4}\\b";//将规则封装成对象Pattern p=Pattern.compile(reg);//让正则对象和要作用的字符串相关联。获取匹配器对象Matcher m=p.matcher(str);/*类似于迭代器*///boolean b=m.find(); //将规则作用到字符串,并进行符合规则的子串查找//System.out.println(m.group());//用于获取匹配后结果。while(m.find()){System.out.println(m.group());System.out.println(m.start()+"...."+m.end());}}}结果:
来两个练习:
/*练习到底用四种功能中的哪一个呢?或者哪几个呢?思路方式:1、如果只想知道该字符串是否对错,使用匹配2、想要将已有的字符串变成另一个字符串,替换3、想要按照自定的方式将字符串变成多个字符串,切割。获取规则以外的子串4、想要拿到符合需求的字符串子串,获取。获取符合规则的子串*/import java.util.*;class RegexTest1{public static void main(String[] args){Method_Test1();Method_Test2();checkMail();}/*需求:对邮件地址进行校验*/public static void checkMail(){ String mail="abc123@sina.com.cn";String reg="[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+"; //较为精确的匹配reg="\\w+@\\w+(\\.\\w+)+";//相对不太精确的匹配,因为 "1@1.1"也能匹配正确sop(mail.matches(reg));}/*192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30将IP地址进行地址段顺序的排序1、按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位。2、将每一段只保留3位。这样,所有的IP地址都是每一段3位*/public static void Method_Test2(){String ip="192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";ip=ip.replaceAll("(\\d+)","00$1"); //补齐,使每一段至少3位sop(ip);ip=ip.replaceAll("0*(\\d{3})","$1"); //去掉多余的0,使每一段为3位sop(ip);String[] arr=ip.split(" +"); //将字符串转换为数据TreeSet<String> ts=new TreeSet<String>();for(String s:arr) //将数组中的元素添加到TreeSet集合中排序{ts.add(s);}for(String s:ts){sop(s.replaceAll("0*(\\d)","$1")); //将每一段中多余的0去掉,如002-->2}}/*将下列字符串转成:我要学编程*/public static void Method_Test1(){String str="我我...我我...我想要...要要...要要...学学学...学学..编编编..编程..程.程程...程...程";/*将已有字符串变成另一个字符串,使用替换功能1、可以将.去掉2、再将多个重复的内容变成单个内容*/String reg1="\\.+";str=str.replaceAll(reg1,"");sop(str);String reg2="(.)\\1+";str=str.replaceAll(reg2,"$1");sop(str);}public static void sop(Object obj){System.out.println(obj);}}
应用:网页爬虫
旁白:妈呀,终于到正餐了,这个例子就是我开头说的,在网页上抓取数据的应用,来,咱也搞起。。。。
/*网页爬虫*/import java.io.*;import java.util.regex.*;import java.net.*;class RegexTest2{public static void main(String[] args) throws Exception{getMail() ;}public static void getMail() throws Exception{//数据源,从哪里抓取数据URL url=new URL("http://tieba.baidu.com/p/2986729518"); //从贴吧里一大堆求种的贴子里选了一个URLConnection urlconn=url.openConnection();//获取读取流BufferedReader brIn=new BufferedReader(new InputStreamReader(urlconn.getInputStream()));//将抓取的数据存入一个文件中BufferedWriter bwOut=new BufferedWriter(new FileWriter("mailList.txt"));String line=null;String mailReg="[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//将正则表达式封装成对象Pattern p=Pattern.compile(mailReg);while((line=brIn.readLine())!=null){//文本和引擎相关联Matcher m=p.matcher(line);while(m.find()){String str=m.group();bwOut.write(str);bwOut.newLine();bwOut.flush();System.out.println(str);}}}}
结果: 怎么样?
其实还有是有点瑕疵的,上面的截图只能截取部分,看一下文件吧
看到圈红线部分没,这部分肯定是有问题的,毕竟人家发的是QQ邮箱,但是最后截取的去含有字母。。。。。
我们可以在获取的结果里作下判断,如果结果字符串含有@qq,则从数字部分开始。。。但是也有问题,像uff0c开头的还好,后面的就是QQ号了,但是u5b50这样开始的就不好弄了。。。咋办?
看了下网页源代码: 实际上邮箱应该是选中部分,但是结果却是把前面的u300也截取过来了。。。各位看官,有什么方法没?(待续。。。)
0 0
- 黑马程序员---java基础之正则表达式
- 黑马程序员----JAVA基础之正则表达式
- <<黑马程序员>>java基础之正则表达式
- 黑马程序员-java基础之正则表达式
- 黑马程序员 Java基础之正则表达式
- 黑马程序员 java基础之正则表达式
- 黑马程序员--java基础之正则表达式
- 黑马程序员-JAVA基础之正则表达式
- 黑马程序员java基础之之正则表达式
- 黑马程序员-----java基础(之正则表达式的使用)
- 黑马程序员—java基础之反射与正则表达式
- 黑马程序员--JAVA基础复习之正则表达式
- 黑马程序员---从头开始,回忆JAVA基础之正则表达式。
- 黑马程序员—【Java基础篇】之正则表达式
- 黑马程序员——java基础之正则表达式
- 黑马程序员-java基础 正则表达式
- 黑马程序员-JAVA基础-正则表达式
- 黑马程序员:Java基础总结----正则表达式
- scrollerview
- 同一台电脑上多个myeclipse破解的问题
- 代码审查 本地测试经验汇总
- SDUT OJ 约瑟夫问题——链表
- c语言实现循环队列
- 黑马程序员--java基础之正则表达式
- ant构建tomcat7失败
- kyeremal-最大流dinic算法模板-多路增广
- PCH文件
- Hello, everybody.
- 1、MapReduce 工作原理简介(待补充)
- 请禁用VS(C++)2013的链接器的COMDAT选项
- Java读取FTP上的txt文件
- 玩命牛的成长记录(九)——服务