一.regex(正则表达式):Regularexpressions(代替了StringTokenizer);字符串处理利器;在unix流行,perl使用regex更牛。
主要用在字符串匹配、查找和替换。例如:匹配IP(范围小于256)使用正则很好搞;从网页中揪出大量email地址发送垃圾邮件;从网页里揪出链接。包含Matcher(用模式匹配字符串后产生的结果)和pattern。
复制代码 代码如下:
System.out.println("abc".matches("..."));//每个"."表示一个字符
复制代码 代码如下:
System.out.println("ab54564654sbg48746bshj".replaceAll("[0-9]", "-"));//每个"."表示一个字符
二、
复制代码 代码如下:
Pattern p = Pattern.compile("[a-z]{3}");
Matcher m = p.matcher("ggs");//创建匹配给定输入与此模式的匹配器。内部实际上是创建了一个优先状态的自动机(编译原理)
//matcher和matches里待匹配的字符串实际上是CharSequence(接口),不过String实现了该接口,存在多态
System.out.println(m.matches());//若是"ggss"就不匹配了
//可一直接"ggs".matches("[a-z]{3}"),不过上面的有好处,至少效率高了,而且Pattern和Matcher提供了很多功能
三、在regex“. * +”中叫meta Character;ctrl + shift + "/"表示注释,换成""表示去掉注释。
复制代码 代码如下:
"a".matches(".");//true,"."表示任意一个字符,汉字也行
"aa".matches("aa");//true,也就是说普通字符串也可以作为正则表达式
"aaaa".matches("a*");
"".matches("a*");//true
"aaa".matches("a?");//true,一次或者0次
"".matches("a?");//true
"a".matches("a?");//true
"544848154564113".matches("\d{3,100}");//true
//这个是最简单的IP判断,不过若是超过255则判断不出来
"192.168.0.aaa".matches("\d{1,3}\.\d{1,3}\.\d{1,3}\d{1,3}");
"192".matches("[0-2][0-9][0-9]");
四、[abc]表示匹配任意一个字符;[^abc]表示出了abc以外的其他字母(必须还是字母,若是空串也返回false)字符;[a-zA-Z]等价于"[a-z]|[A-Z]"是否是某个大小写字母;[A-Z&&[ABS]]表示大写字母中取ABS中任一个。
复制代码 代码如下:
//发现|和||没区别,&和&&有区别,不知道这么理解对不对
System.out.println("C".matches("[A-Z&&[ABS]]"));//false
System.out.println("C".matches("[A-Z&[ABS]]"));//true
System.out.println("A".matches("[A-Z&&[ABS]]"));//true
System.out.println("A".matches("[A-Z&[ABS]]"));//true
System.out.println("C".matches("[A-Z|[ABS]]"));//true
System.out.println("C".matches("[A-Z||[ABS]]"));//true
五、w 单词字符:[a-zA-Z_0-9] 进行用户名匹配时;s 空白字符:[ tnx0Bfr]; S 非空白字符:[^s] ;W 非单词字符:[^w] 。
复制代码 代码如下:
" ntr".matches("\s{4}");//true
" ".matches("\S");//false
"a_8".matches("\w{3}");//true
//“+”表示一次或者多次
"abc888&^%".matches("[a-z]{1,3}\d+[&^#%]+");//true
System.out.println("\".matches("\\"));//true
六、POSIX 字符类(仅 US-ASCII)
复制代码 代码如下:
p{Lower} 小写字母字符:[a-z] ;p{Upper} 大写字母字符:[A-Z] ;p{ASCII} 所有 ASCII:[x00-x7F] ;p{Alpha} 字母字符:[p{Lower}p{Upper}] ;p{Digit} 十进制数字:[0-9] 。
七、边界匹配器
^ 行的开头
$ 行的结尾
b 单词边界
B 非单词边界
A 输入的开头
G 上一个匹配的结尾
Z 输入的结尾,仅用于最后的结束符(如果有的话)
z 输入的结尾
复制代码 代码如下:
"hello world".matches("^h.*");//^行的开头
"hello world".matches(".*ld$");//$行的结尾
"hello world".matches("^h[a-z]{1,3}o\b.*");//b单词边界
"helloworld".matches("^h[a-z]{1,3}o\b.*");
" n".matches("^[\s&&[^\n]]*\n$");//判断空白行,空白行开头是空白符
八、还可以在find方法下使用m.start()和m.end()返回开始位置和结束位置的下一个;若是找不到则出错。
复制代码 代码如下:
Pattern p = Pattern.compile("\d{3,5}");
String s = "133-34444-333-00";
Matcher m = p.matcher(s);
m.matches();//matches匹配全部字符串
m.reset();
m.find();
m.find();
m.find();//尝试查找与该模式匹配的输入序列的下一个子序列
m.find();
m.lookingAt();
m.lookingAt();
m.lookingAt();
m.lookingAt();
九、字符串替换
复制代码 代码如下:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestRegexReplacement {
public static void main(String[] args) {
Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//后面的参数是整形,表示“大小写不敏感”
Matcher m = p.matcher("Java java hxsyl Ilovejava java JaVaAcmer");
while(m.find()) {
System.out.println(m.group());//m.group会输出所有的java(忽略大小写)
}
String s = m.replaceAll("Java");//String也有该方法
System.out.println(s);
m.reset();//一定要加,因为find和matcher相互影响
StringBuffer sb = new StringBuffer();
int i = 0;
while(m.find()) {
i++;
//不能直接写成i&1必须转化为boolean
if((i&1)==1) {
m.appendReplacement(sb, "Java");
}else {
m.appendReplacement(sb, "java");
}
}
m.appendTail(sb);//把找到的最后一个java后边的剩余字符串加上
System.out.println(sb);//不加reset的话只输出了Acmer
}
}
十、分组
复制代码 代码如下:
Pattern p = Pattern.compile("(\d{3,5})([a-z]{2})");
String s = "123aaa-77878bb-646dd-00";
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group());
System.out.println(m.group(1));//输出每对符合的 数字
System.out.println(m.group(2));//输出每对符合的 字母
}
十一、抓取网页中的email
复制代码 代码如下:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmailSpider {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
BufferedReader br = new BufferedReader(new FileReader("F:\regex.html"));
String line = "";
try {
while((line=br.readLine())!=null) {
solve(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void solve(String line) {
// TODO Auto-generated method stub
//正则表达式要是不满足相应功能的话不会出错,因为他是字符串
Pattern p = Pattern.compile("[\w[.-]]+@[\w[.-]]+\.[\w]+");
Matcher m = p.matcher(line);
while(m.find()) {
System.out.println(m.group());
}
}
}
十二、代码统计
复制代码 代码如下:
View Code
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CoderCount {
static long normalLines = 0;
static long commentLines = 0;
static long whiteLines = 0;
public static void main(String[] args) {
File f = new File("D:\share\src");
File[] codeFiles = f.listFiles();
for(File child : codeFiles){
if(child.getName().matches(".*\.java$")) {
solve(child);
}
}
System.out.println("normalLines:" + normalLines);
System.out.println("commentLines:" + commentLines);
System.out.println("whiteLines:" + whiteLines);
}
private static void solve(File f) {
BufferedReader br = null;
boolean comment = false;
try {
br = new BufferedReader(new FileReader(f));
String line = "";
while((line = br.readLine()) != null) {
line = line.trim();
//readLine读出字符串后就把后面的换行去掉啦
if(line.matches("^[\s&&[^\n]]*$")) {
whiteLines ++;
} else if (line.startsWith("")) {
commentLines ++;
comment = true;
} else if (line.startsWith("")) {
commentLines ++;
} else if (true == comment) {
commentLines ++;
if(line.endsWith("*/")) {
comment = false;
}
} else if (line.startsWith("//")) {
commentLines ++;
} else {
normalLines ++;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br != null) {
try {
br.close();
br = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
十三、Quantifiers
包括?*+;默认全是Greedy,还有Reluctant和Possessive(独占性的)。
复制代码 代码如下:
//加上分组是为了看得更清晰一些
Pattern p = Pattern.compile("(.{3,10})+[0-9]");
String s = "aaaa5bbbb6";//长度是10
Matcher m = p.matcher(s);
if(m.find()) {
System.out.println(m.start() + "----" + m.end());
}else {
System.put.println("Not match!");
}
十四、补充(非捕获组)
复制代码 代码如下:
//非捕获组的意思和字面相反,意思是若是符合则捕获
Pattern p = Pattern.compile("(?=a).{3}");
String s = "444a66b";
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group());
}
十五、Back Reference
复制代码 代码如下:
Pattern p = Pattern.compile("(\d\d)\1");
String s = "1212";
Matcher m = p.matcher(s);
System.out.println(m.matches());
十六、flags的简写
"."是不匹配换行的,记住CASE_INSENSITIVE就行了,简写“通过嵌入式标志表达式 (?i) 也可以启用不区分大小写的匹配”。



