Java正则表达式基础及应用.docx
- 文档编号:24693199
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:15
- 大小:1.18MB
Java正则表达式基础及应用.docx
《Java正则表达式基础及应用.docx》由会员分享,可在线阅读,更多相关《Java正则表达式基础及应用.docx(15页珍藏版)》请在冰豆网上搜索。
Java正则表达式基础及应用
正则表达式基础及Java正则表达式应用
陈敏刚2016.7.14
【引言】由于研究需要对日志信息、视频信息作大数据的分析,特整理以下正则表达式的各种用法,比如如何提取Apache日志信息中的IP地址和访问时间,如何设计简单的网络爬虫程序等,主要通过Java语言描述,其它语言如Python思路也基本相通。
1.正则表达式基本概念
正则表达式,也叫RegularExpressions,它实际上是用来搜索、匹配字符串的模式。
正则表达式一般要表达三个要素。
(1)要匹配的字符,如[0-9];
(2)字符的数量或者有几个这样的字符,如{2,4},即2-4个字符,需要用大括号括起来。
(3)字符的位置在哪儿?
如\b表示字符的边界,border。
要熟悉以上正则表达式的基本元素,可以对应于正则表达式的要素,分为字符类、数量类和位置类。
(1).代表1个字符的通配符
比如,t.n可匹配“tan,ten,ton,tpn”等
(2)[]代表字符集,只有方括号里指定的字符才能参与匹配,方括号内只能匹配单个字符,但可用连字符-来表示范围,如[0-9]表示0-9中的一个数字;
比如,t[aeiou]n,可匹配“tan,ten,ton”,但不匹配tpn、toon等。
[^]表示排斥性字符集。
比如,[^x][a-z]+,可匹配除x开头的所有单词。
(3)()用来分组,在()内可以使用“|”操作表示“或”,方括号[]不能用“|”
比如,t(a|e|i|o|u|oo)可匹配“tan,ten,ton”,还可匹配toon。
(4)^表示起始位置、\b表示单词边界
星号*表示0个或多个
加号+表示1或多个
问号?
表示0个或1个
n就是写个数字表示重复多少次
[0-9]+来查找年份,字符为数字,数字出现1个或多个。
由于正则表达式比较难用,所以引入一些简写方式,比如\d表示数字(digit)[0-9],\s表示空白符(space)、\w表示单词字符(word)[a-zA-Z_0-9]。
正则表达式写起来还是比较麻烦,因此经常需要利用工具,比如QRe,
\b(href)=(‘[^’]+’)
上面正则表达式的解释:
(1)两个圆括号()代表两个group
(2)\b表示单词边界,(href)表示group1
(3)(‘[^’]+’)表示group2,字符是‘开始,’结束,中间1个或多个非’字符,整个匹配字符串的称为group0
2.正则表达式的基本应用
Java中正则表达式,需要用到java.util.regex包,这个包主要有两个类,分别是Pattern类(模式类)和Matcher类(匹配类)
2.1字符串的分割
//将正则表达式”[,\\s]+”编译成模式类对象p,\\s表示空格,并用了\表示转义符
Patternp=Ppile(“[,\\s]+”);
//调用p的split方法分割字符串
String[]result=p.split("one,two,threefour,five");
2.2字符串的匹配验证
//开始的^表示字符串开始,结尾的$表示字符串结尾
//@前表示1到多个非@字符
//@后“[\\w]+”表示1到多个word,\\w表示\w的转义
//“(\\.[\\w]+)*”表示多个”.word”的模式
Stringpattern="^[^@]+@[\\w]+(\\.[\\w]+)*$";
Stringemail="dstang2000@";
booleanok=Pattern.matches(pattern,email);
2.3字符串的替换
importjava.util.regex.*;
publicclassRegexReplacement{
publicstaticvoidmain(String[]args)throwsException{
Patternpattern=Ppile("cat");
//调用pattern对象的matcher方法得到matcher对象
Matchermatcher=pattern.matcher("onecat,twocatsintheyard");
//StringBuffer是可变字符串类
StringBuffersb=newStringBuffer();
//找到匹配的字符串cat,就将该字符串整体替换成”bigcat”
//找到第1个cat后,sb的值为“onebigcat”,找到第2个cat后,sb的值为“onebigcat,twobigcat”
while(matcher.find()){
matcher.appendReplacement(sb,"big$0");
}
//将后面的”sintheyard”加到sb后面,即“onebigcat,twobigcatsintheyard”
matcher.appendTail(sb);
System.out.println(sb.toString());
}
}
2.4从文档中找到自己需要的信息(非常重要)
从文档中找到自己需要的信息非常重要,比如从网页的内容中找到链接的网址,或从视频文件信息中找到视频文件的时长等等,下面的例子演示如何从网页的内容中找到链接的网址。
importjava.util.regex.*;
classRegexHref{
publicstaticvoidmain(String[]args){
//\\s*(href|src)\\s*代表(href|src)前面、后面有0或多个空格
//=后面‘\\s*(\"([^\"]*\")’代表\”开头,0或多个非\”,\”结尾的组
//’|(\'[^\']*\')’,表示或者‘’之间的字符
//([^\'\">\\s]+)
StringpatternString=
"\\s*(href|src)\\s*=\\s*(\"([^\"]*\")|(\'[^\']*\')|([^\'\">\\s]+))";
//测试的网页内容
Stringtext=" //aaa.htm\">bbb //ccc.htm\'>ccc"; Patternpattern=Ppile(patternString,Pattern.CASE_INSENSITIVE); Matchermatcher=pattern.matcher(text); StringBufferbuffer=newStringBuffer(); while(matcher.find()){ //整个捕获,相当于goup(0) buffer.append("获捕到"+matcher.group()); //捕获中的一部分(第2对圆括号对应的,即是网址) buffer.append("其中网址为"+matcher.group (2)); buffer.append("\r\n"); } System.out.println(buffer.toString()); } } 2.5更多正则表达式的例子 参考: (1)匹配美国的社会安全号码 假设我们要在文本文件中搜索美国的社会安全号码。 这个号码的格式是123-12-1234。 用来匹配它的正则表达式如图1所示。 在正则表达式中,连字符(“-”)有着特殊的意义,它表示一个范围,比如从0到9。 因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“\”。 图1匹配所有123-12-1234形式的社会安全号码 【注意: 但在Java中连字符-不需要转义符\】 在Java中匹配的模式写为: Stringpattern1="[0-9]{3}-[0-9]{2}-[0-9]d{4}"; //或通过预定义的字符\d来简化,但需要加转义符\,所以是\\d Stringpattern1="\\d{3}-\\d{2}-\\d{4}"; 假设进行搜索的时候,你希望连字符号可以出现,也可以不出现即,999-99-9999和999999999都属于正确的格式。 这时,你可以在连字符号后面加上“? ”数量限定符号,如图2所示: Stringpattern2="[0-9]{3}-? [0-9]{2}-? [0-9]d{4}"; Stringpattern2="\\d{3}-? \\d{2}-? \\d{4}"; (2)匹配上海的汽车牌照号码 上海汽车牌照的一种格式是沪+A-Z.五个字符,如沪A.25F63,沪B.88888等。 在Java中匹配的模式写为: Stringpattern="沪[A-Z]\\.\\w{5}"; (3)将字符串中的生日信息中提取出年、月、日的信息 假设要从格式为“June26,1951”的生日日期中提取出年月日信息 在Java中匹配的模式写为: Stringpattern="([a-z]+)\\s*([0-9]{1,2}),\\s*([0-9]{4})"; importjava.util.regex.*; publicclassRegexBirthday{ publicstaticvoidmain(String[]args){ StringpatternString="([a-z]+)\\s*([0-9]{1,2}),\\s*([0-9]{4})"; Stringtext="MileswasbornonJune2,1978inNingbo"; Patternpattern=Ppile(patternString,Pattern.CASE_INSENSITIVE); Matchermatcher=pattern.matcher(text); //StringBufferbuffer=newStringBuffer(); Stringyear=null; Stringmonth=null; Stringday=null; while(matcher.find()){ month=matcher.group (1); day=matcher.group (2); year=matcher.group(3); } System.out.println("Milesbirthdayis"+year+""+month+""+day); } } 程序输出: Milesbirthdayis1978June2 (4)匹配HTML 分析HTML页面内FONT标记的所有属性。 HTML页面内典型的FONT标记如下所示: 程序需要输出如下键值对: face=Arial,Serif size=+2 color=red 第1步提取出尖括号内的内容: 第2步利用group,将属性分割成键值对 3.正则表达式的综合应用 3.1简单的网络爬虫 【源代码】 import.URL; importjava.io.*; importjava.util.*; importjava.util.concurrent.*; importjava.util.regex.*; importjava.nio.charset.*; classURLCrawler { publicstaticvoidmain(String[]args)throwsException{ //并发队列 finalConcurrentLinkedQueue urls.add(""); intcnt=0; while(! urls.isEmpty()){ finalStringurl=urls.poll(); System.out.println(url); //启动匿名线程 newThread(){ publicvoidrun(){ try{ Stringcontent=download(newURL(url),"gb2312");//下载网页内容List urls.addAll(moreUrl); }catch(Exceptionex){ ex.printStackTrace(); } } }.start(); if(cnt++>10)break;//当爬到的网址内容超过10个,停止 try{ Thread.sleep(4000); } catch(InterruptedExceptionex){ } } } staticList StringpatternString= "\\s*href\\s*=\\s*(\"([^\"]*\")|(\'[^\']*\')|([^\'\">\\s]+))\\s*"; Patternpattern=Ppile(patternString,Pattern.CASE_INSENSITIVE); Matchermatcher=pattern.matcher(text); List while(matcher.find()){ Stringhref=matcher.group (1); href=href.replaceAll("\'","").replaceAll("\"",""); if(href.startsWith("http: ")) list.add(href); } returnlist; } //下载网页内容 staticStringdownload(URLurl,Stringcharset)throwsException{ try(InputStreaminput=url.openStream(); ByteArrayOutputStreamoutput=newByteArrayOutputStream()){ byte[]data=newbyte[1024]; intlength; while((length=input.read(data))! =-1){ output.write(data,0,length); } byte[]content=output.toByteArray(); returnnewString(content,Charset.forName(charset)); } } } 3.2网站日志分析 ApacheHTTP日志服务器的标准日志: 127.0.0.1-frank[10/Oct/2000: 13: 55: 36-0700]"GET/apache_pb.gifHTTP/1.0"2002326 如何提取IP和访问日期信息? StringpatternIP="\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"; StringpatternDate="\\[[^[]]+\\]"; 【源代码】 importjava.util.regex.*; publicclassRegexLog{ publicstaticvoidmain(String[]args){ StringpatternIP="\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"; StringpatternDate="\\[[^\\[]+\\]"; Stringtext="127.0.0.1-frank[10/Oct/2000: 13: 55: 36-0700]"+"\""+"GET/apache_pb.gifHTTP/1.0"+"\""+"2002326"; Patternpattern1=Ppile(patternIP,Pattern.CASE_INSENSITIVE); Patternpattern2=Ppile(patternDate,Pattern.CASE_INSENSITIVE); Matchermatcher1=pattern1.matcher(text); Matchermatcher2=pattern2.matcher(text); Stringip=null; Stringdate=null; while(matcher1.find()){ ip=matcher1.group(); } System.out.println("IPis"+ip); while(matcher2.find()){ date=matcher2.group(); } System.out.println("Dateis"+date); } } 程序输出: IPis127.0.0.1 Dateis[10/Oct/2000: 13: 55: 36-0700] 4.结束语 许多语言,包括Perl、PHP、Python、JavaScript,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高级“搜索-替换”功能。 本文只是列出了正则表达式一些常见的应用,要精通正则表达式还需要多多编程实践。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 正则 表达式 基础 应用