Java正则表达式基础及应用.docx

上传人:b****4 文档编号:11353543 上传时间:2023-05-31 格式:DOCX 页数:15 大小:1.18MB
下载 相关 举报
Java正则表达式基础及应用.docx_第1页
第1页 / 共15页
Java正则表达式基础及应用.docx_第2页
第2页 / 共15页
Java正则表达式基础及应用.docx_第3页
第3页 / 共15页
Java正则表达式基础及应用.docx_第4页
第4页 / 共15页
Java正则表达式基础及应用.docx_第5页
第5页 / 共15页
Java正则表达式基础及应用.docx_第6页
第6页 / 共15页
Java正则表达式基础及应用.docx_第7页
第7页 / 共15页
Java正则表达式基础及应用.docx_第8页
第8页 / 共15页
Java正则表达式基础及应用.docx_第9页
第9页 / 共15页
Java正则表达式基础及应用.docx_第10页
第10页 / 共15页
Java正则表达式基础及应用.docx_第11页
第11页 / 共15页
Java正则表达式基础及应用.docx_第12页
第12页 / 共15页
Java正则表达式基础及应用.docx_第13页
第13页 / 共15页
Java正则表达式基础及应用.docx_第14页
第14页 / 共15页
Java正则表达式基础及应用.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Java正则表达式基础及应用.docx

《Java正则表达式基础及应用.docx》由会员分享,可在线阅读,更多相关《Java正则表达式基础及应用.docx(15页珍藏版)》请在冰点文库上搜索。

Java正则表达式基础及应用.docx

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{

//并发队列

finalConcurrentLinkedQueueurls=newConcurrentLinkedQueue<>();

urls.add("");

intcnt=0;

while(!

urls.isEmpty()){

finalStringurl=urls.poll();

System.out.println(url);

//启动匿名线程

newThread(){

publicvoidrun(){

try{

Stringcontent=download(newURL(url),"gb2312");//下载网页内容ListmoreUrl=parse(content);//解析网址

urls.addAll(moreUrl);

}catch(Exceptionex){

ex.printStackTrace();

}

}

}.start();

if(cnt++>10)break;//当爬到的网址内容超过10个,停止

try{

Thread.sleep(4000);

}

catch(InterruptedExceptionex){

}

}

}

staticListparse(Stringtext){

StringpatternString=

"\\s*href\\s*=\\s*(\"([^\"]*\")|(\'[^\']*\')|([^\'\">\\s]+))\\s*";

Patternpattern=Ppile(patternString,Pattern.CASE_INSENSITIVE);

Matchermatcher=pattern.matcher(text);

Listlist=newArrayList<>();

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,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高级“搜索-替换”功能。

本文只是列出了正则表达式一些常见的应用,要精通正则表达式还需要多多编程实践。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2