java.util.regex包下的Pattern
每日心得
今天只上了上午的课,因为班上大部分人都感冒了,所以公司放了四天假,来让我们调养。
Pattern
来源于Linux
,unix
系统,用于处理字符串。其本身包含一个字符串,用于在java中呈现正则表达式,正则表达式是一个字符串,是一种通用的规范,通过这个工具类来使用,正常情况下可跨语言来使用,这个类本身不代表正则表达式。
Pattern p=Pattern.compile("a*b");//正则表达式
Matcher m=p.matcher("aaaaab");//进行比较的字符串
boolean b =m.matches();返回结果
boolean b=Pattern.matches("a*b","aaaaab");
上方两种代码效果一致,下面一种简写版本,但只适合于练习时使用,一般开发时不会使用,因为如果要多次使用这个正则表达式,就等于重复使用上方三行代码,但那三行代码中部分代码是不需要多次使用的,例如第一行。在多线程并发时,Pattern
是线程安全的,但Matcher
并不安全。
正则表达式有很多种表现方式,有一点需要注意"\\","\",要用四个反斜杠表示java的两个反斜杠,因为是转义字符,像\n
等必须在前面再加一个\符号.在windows
系统中,能够识别\n
换行符,\r
确认符,但Linux
系统不能识别\r
,所以有时候当windows
的文件转成linux
时可能会多出很多\r
.
[abc]//匹配中间的一个,需要匹配几个就在后面加几次[abc][abc]类似这种;
[^abc]//^取反,除abc以外;
[a-zA-Z]//表示范围,闭区间,范围有限制,与ASCll编码有关,从小到大;单个字符
[a-d[m-p]]or[a-dm-p]//并集;
[a-z&&[def]]//取交集,即d,e,f;
[a-z&&[^bc]]//a-z除bc外;
[a-z&&[^m-p]]//与上一致;
预定义字符类型
. //匹配任意字符,在操作系统不同的情况下,可能因为行的原因,会不同,单匹配 . -->"\\.”"[.]";
\d//匹配一个数字;
\D//匹配一个非数字;
\w//[a-zA-Z_0-9],单词字符,匹配这里面的一个
\s//匹配空白字符
边界字符
^//以什么开头,用在搜索时;
$//以什么结尾;
数量词
Greedy(贪婪型)
X?//一个或者一个都没有
X*//0个或者更多
X+//一个或者更多
X{n}//刚好n次
X{n,}// 至少n次
X{n,m}// 至少n次,但是不超过m次
Reluctant(惰性型)
X??//在贪婪的基础上加一个?,含义一样
Possessvie(支配型)
X?+//在贪婪的基础上加一个+,含义一样
数量词有三种,它们在进行字符串匹配时并没有区别,但在进行子串查找时会有区别。
第一种:拿整个字符串与正则表达式匹配,如果成功,则返回,不成功,则会去掉最后一个字符,
再次匹配,直到匹配或者去到没有字符为止。
第二种:先读取字符串的第一个字符,与正则表达式进行匹配,若成功,则返回。从当前位置,
继续读取其他字符,进行匹配,如果不成功,则读取下一个字符,和当字符一起和正则表达式
进行匹配;
第三种:拿整个字符串和正则表达式进行匹配,根据数量词的最大数量进行匹配
m.find
,用于查询单个,可使用循环语句查询多个。m.group();查询后获值,m.replaceAll();替换;
分组与捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
零组始终代表整个表达式。
以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。
还有一个扒取小说的作业,我这个是扒取到指定的文件夹到本地的文本文件:
第一个扒取目录中每个章节的地址:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class novel{
public static void main(String[] args) throws Exception{
novelcontent n=new novelcontent();
String url="https://www.biqugg.com/xs/15300/";
URLConnection urlConnection = new URL(url).openConnection();
HttpURLConnection conn = (HttpURLConnection)urlConnection;
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"utf-8"));
StringBuilder html=new StringBuilder();
String s =null;
while((s=reader.readLine())!=null){
//System.out.println(s);
html.append(s);
}
String jh=null;
Pattern p =Pattern.compile("<div(.+?)《沧元图》正文(.+?)</div>");
Matcher m=p.matcher(html);
while(m.find()){
jh=m.group();
//System.out.println(jh);
}
Pattern p2 =Pattern.compile("<dl>(.+?)</dl>");
Matcher m2=p2.matcher(jh);
while(m2.find()){
jh=m2.group();
//System.out.println(jh);
}
Pattern p3 =Pattern.compile("<dd>(.+?)</dd>");
Matcher m3=p3.matcher(jh);
while(m3.find()){
jh+=m3.group();
}
String jh1=jh;
String b="**";
Pattern p4 =Pattern.compile("\">(.+?)<");
Pattern p5 =Pattern.compile("\"(.+?)\"");
Matcher m4=p4.matcher(jh);
Matcher m5=p5.matcher(jh1);
while(m4.find()&&m5.find()){
jh=m4.group(1);
jh1=m5.group(1);
if(jh.equals("第二十一集 第十章 洞天阁**")){
jh=jh.replace(b,"");
}
n.context(jh1, jh);
}
}
}
因为有一个章节中带有号,而文件命名不能使用号,所以将那章的*去除了;
还有一个扒取具体小说内容的类
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class novelcontent {
public static void main(String[] args) throws Exception {
//context("15589163.html","洞天阁");
}
public void context(String urls,String name) throws Exception{
String path="D://novel//";
String filenameTemp;
filenameTemp =path+name+".txt";
File filename = new File(filenameTemp);
filename.createNewFile();
FileWriter fw =new FileWriter(filename);
BufferedWriter bw=new BufferedWriter(fw);
String url="https://www.biqugg.com/xs/15300/"+urls;
URLConnection urlConnection = new URL(url).openConnection();
HttpURLConnection conn = (HttpURLConnection)urlConnection;
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"utf-8"));
StringBuilder html=new StringBuilder();
String s =null;
while((s=reader.readLine())!=null){
//System.out.println(s);
html.append(s);
}
String jh=null;
Pattern p =Pattern.compile("<div id=\"content\"(.+?)</div>");
Matcher m=p.matcher(html);
while(m.find()){
jh=m.group();
//System.out.println(jh);
}
Pattern p2 =Pattern.compile(" (.+?)<br />");
Matcher m2=p2.matcher(jh);
while(m2.find()){
jh=m2.group(1);
bw.write(jh+"\n\n");
}
bw.flush();
bw.close();
fw.close();
}
}
部分注释是测试时候用的。