package cn.itcast.exp;
/*
正则表达式:其实一种规则,有自己特殊的应用,其作用就是针对于字符串进行操作。
正则:就是用于操作字符串的规则,其中这些规则使用了一些字符表示。
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
注意:任何预定义字符没有加上数量词之前都只能匹配一个字符
Greedy 数量词 X代表预定义字符
X? 一次或一次也没有
X* 零次或多次
X+ 一次或多次
X{n} X,恰好n次
X{n,} X,至少n次
X{n,m} X,至少n次,但是不超过m次
. 一个字符
* 匹配0次或多个字符,a* 就是匹配一个或多个a,匹配串必须都是a
+ 匹配一个或多个字符
?匹配0个或一个
{}-->表示范围
[]表示某一个字符的范围
范围词
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
注意:范围词里面不管内容有多长,没有数量词的匹配都只能匹配一个字符
范围
[]表示某一个字符的范围
^ 代表非或除了什么以外的意思
- 范围
| 或
&& 并
*/
public class Demo {
public static void main(String[] args) {
//简单认识正则表达式
System.out.println("a&f".matches("..."));
System.out.println("2".matches("\\d")); //\\d代表一个占位符,字符串只能有一个数字才能返回true
System.out.println("非数字:"+"d".matches("\\D")); //true
System.out.println("空白字符:" + " ".matches("\\s")); //true
System.out.println("非空白字符:" + " ".matches("\\S")); // false
System.out.println("单词字符:" + "a".matches("\\w")); //true
System.out.println("非单词字符:" + "a".matches("\\W")); //false
p(" \n\r\t".matches("\\s{4}"));
p(" ".matches("\\S"));
p("a_8".matches("\\w{3}"));
p("abd888&^%".matches("[a-z]{1,3}\\d+[&^%#]+"));
p("\\".matches("\\\\"));//匹配一个反斜杠
//POSIX Style unix的统一 用的不是太多
p("a".matches("\\p{Lower}"));//英文的小写字母
System.out.println("?表示一次或一次也没有:"+"1".matches("\\d?"));
System.out.println("*表示零次或多次:"+"13243243534".matches("\\d*"));
System.out.println("+表示一次或多次:"+"13243243534".matches("\\d+"));
System.out.println("{次数} 恰好出现n次:"+"132432".matches("\\d{6}"));
System.out.println("{次数,} 至少出现指定的位数:"+"13243243534".matches("\\d{3,}"));
System.out.println("{次数1,次数2} 指定出现次数的范围:"+"13243".matches("\\d{3,5}"));
System.out.println("abc".matches("[abc]")); //false
System.out.println("abc".matches("[abc]{3}")); //true
System.out.println("@".matches("[^abc]")); //true
System.out.println( "一个字符出现在a-z之间"+"a".matches("[a-z]"));
System.out.println( "一个所有字母"+"A".matches("[a-zA-Z]"));
"aaaa".matches("a."); // false
"aaaa".matches("a*"); // true
"aaaa".matches("a+"); //true
"aaaa".matches("a?"); // false
p("a".matches("."));
p("aa".matches("aa"));
p("aaaa".matches("a*"));
p("aaaa".matches("a+"));
p("".matches("a*"));
p("aaaa".matches("a?"));
p("".matches("a?"));
p("a".matches("[abc]"));//取出中括号abc其中的一个与a进行匹配
p("a".matches("[^abc]"));//除了a,b,c以外的字符与a进行匹配
p("a".matches("[a-zA-Z]"));//所有的大小写字母与a进行匹配
p("a".matches("[a-z]|[A-Z]"));//a-z或A-Z与a进行匹配
p("a".matches("[A-Z]&&[RFG]"));
p("2321432456789765432".matches("\\d{3,100}"));//数字的长度在3到100之间
p("192.168.0.aaa".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
p("192".matches("[0-2][0-9][0-9]"));
//\d代表0-9的任何一个数组
//replaceAll把所有的数字替换成-
//在java中一个反斜杠(\)代表转义,
//"\\"-->输出为\ 规定\d才代表0-9的任何一个数组
//一定要注意\d在java中是\\d
System.out.println("adsa3432fdsfs".replaceAll("\\d", "-"));
}
public static void p(boolean matches) {
System.out.println(matches);
}
}
package cn.itcast.exp;
import java.util.Arrays;
/*
正则表达式的方法:
匹配:
matches()
切割:
split()
替换:
String replaceAll(String regex, String replacement)
使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的每个子字符串。
查找:
*/
public class Demo2 {
public static void main(String[] args) {
matchsPhone("15224816289");
matchsTel("0394-7410747");
testSplit1();
repalceAll1();
repalceAll2();
}
//匹配手机号 第一位只能是1 第二位 3 5 4 7 8 长度11位
public static void matchsPhone(String phone){
String reg = "1[35478]\\d{9}";
System.out.println(phone.matches(reg)?"合法手机号":"非法");
}
//固定电话 区号-主机号 区号:首位0 长度3~4位 主机号 首位不能为0 长度7~8
public static void matchsTel(String tel){
System.out.println(tel.matches("0\\d{3,4}-[1-9]\\d{6,7}")?"合法固话":"非法");
}
//切割
public static void testSplit1(){
String str = "大 话 西 游";
String[] datas = str.split(" +");
System.out.println(Arrays.toString(datas));
}
//根据重叠词进行切割
public static void testSplit2(){
String str = "大话话西游游222222222222你猜";
String[] s = str.split("(.)\\1+"); //如果正则的内容需要被复用,那么需要对正则的内容进行分组。分组的目的就是为了提高正则的复用性。
//组号不能指定,组号是从1开始。
System.out.println(Arrays.toString(s));
/*
( ) 分组: 分组的目的就是为了提高正则的复用性。 组号不能指定,组号是从1开始。
((A)(B(C)))
第一组:((A)(B(C)))
第二组:(A)
第三组:(B(C))
第四组:(C)
\1: 引用第一组所匹配到的内容
\2: 引用第二组所匹配到的内容
\3: 引用第三组所匹配到的内容
。。。。。。。。
*/
}
//替换
public static void repalceAll1(){
String str = "如有需求请联系:15224816289 如有需求请联系:15224816289 ";
String reg = "1[34578]\\d{9}";
str = str.replaceAll(reg, "****");
System.out.println(str);
}
//变成 把重叠词换成一个词
public static void repalceAll2(){
String str = "大大大话话西西游游游2222222";
str = str.replaceAll("(.)\\1+", "$1");
//如果需要再replaceAll()方法正则的外部引用组的内容,那么使用"$组号"
System.out.println(str);
}
}
package cn.itcast.exp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
查找: 使用Pattern类
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,
依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,
所以多个匹配器可以共享同一模式。因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
查找需要使用的对象:
1.Pattern(正则对象)
2.Matcher(匹配器对象)
匹配器使用的方法:
1.find() 通知匹配器去匹配字符串,查找符合规则的字符串。
2.group() 获取符合规则的子串。
注意: 使用group()的时候一定要先调用find()让匹配器去查找符合规则的字符串,否则报错。
Matcher类的方法:
metches 永远匹配整个字符串
find 找子串
lookingAt 每次从头上找子串
注意:
在metches与find一起用的时间,
metches在匹配的时候,如果匹配不成功,会把光标停在不匹配的哪里,你在调用find,
会接着上一次的光标进行匹配,如果你想从头开始,需要用reset方法重置一下
*/
public class Demo3 {
public static void main(String[] args) {
//public static Pattern compile(String regex)
//将给定的正则表达式编译到模式中。
//把regex这个正则表达式编译下,放到Pattern这个模式中,编译好了,当你再拿这个字符串匹配的时候,速度回快一些
Pattern pattern = Pattern.compile("[a-z]{3}");
//[a-z]{3}-->代表三个字母,都是a-z范围
Matcher matcher = pattern.matcher("dfg");
//pattern这个模式匹配dfg这个字符串
//matcher 匹配方法
//Matcher 匹配器
matcher.matches(); //匹配是否成功
//27--33行的代码执行的速度快 36行慢些 没有编译
"dfg".matches("[a-z]{3}");
System.out.println("---------------------");
Pattern pat = Pattern.compile("\\d{3,5}");
String s = "123-34354-123-00";
Matcher m = pat.matcher(s);
p(m.matches());//模式串与s全部进行匹配
m.reset();//注意此方法,重置匹配器
p(m.find());//模式串在s找一个子串进行匹配
p(m.start()+"-"+m.end());
p(m.find());
p(m.start()+"-"+m.end());
p(m.find());
p(m.start()+"-"+m.end());
p(m.find());
//p(m.start()+"-"+m.end());//根据模式串进行匹配的时候,只有找到子串才可以使用start与end方法
System.out.println("---------------------");
p(m.lookingAt());
testGroup1();
//查找长度不定的子串
/*testGroup();
test();
test1();
test2();*/
}
public static void testGroup1() {
//\\d{3,5}[a-z]{2}-->这组正则表达式,用小括号,把他们分开,分成两组,再加上子串本身,共三组,
//group默认数组子串的全部
// -->(\\d{3,5})([a-z]{2})-->分组,在多个()时候,只数左小括号,按照1,2,3,4,5...进行编号,在grounp中,直接grounp(n) n代表你想调用的子串
Pattern p5 = Pattern.compile("(\\d{3,5})([a-z]{2})");
String s5 = "132aa-1235bb-132zz-00";
Matcher m5 = p5.matcher(s5);
while(m5.find()){//查找子串
p(m5.group(0));
}
}
//查找长度不定的子串
public static void testGroup() {
Pattern p2 = Pattern.compile("\\d{3,5}[a-z]{2}");
String s1 = "132aa-1235bb-132zz-00";
Matcher m1 = p2.matcher(s1);
while(m1.find()){//查找子串
p(m1.group());
}
}
public static void p(Object o) {
System.out.println(o);
}
//找到固定三个字母组成的单词
public static void test() {
String content = "da jia computer fly";
String reg = "\\b[a-zA-Z]{3}\\b";
//先把字符串的正则编译成Patter对象。
Pattern p = Pattern.compile(reg);
//使用正则对象匹配字符串用于产生一个Matcher对象
Matcher m = p.matcher(content);
/*
System.out.println("有符合规则的字符串吗?"+m.find());
System.out.println("结果:"+m.group());
*/
while(m.find()){
System.out.println(m.group());
}
}
//查找字符串中的java,区分大小写
public static void test1() {
Pattern p = Pattern.compile("java");
Matcher ma = p.matcher("java Java JAVA JaVa IloveJAVA you hateJava");
while(ma.find()){
System.out.println(ma.group());;//输出匹配到的子串 分组
}
}
//不区分大小写的使用
public static void test2() {
Pattern p1 = Pattern.compile("java",Pattern.CASE_INSENSITIVE);// Pattern.CASE_INSENSITIVE 启用不区分大小写的匹配。
Matcher ma1= p1.matcher("java dsfs Java JAVA JaVa IloveJAVA you hateJava dsfds");
//匹配的时候把dsfs Java看成一个串
StringBuffer buf = new StringBuffer();
int i=0;
while(ma1.find()){
i++;
if(i%2==0){
ma1.appendReplacement(buf, "java");
}else{
ma1.appendReplacement(buf, "JAVA");
}
}
ma1.appendTail(buf);
}
}
package cn.itcast.exp;
/*
单词边界匹配器
\b 单词边界匹配器只是代表了单词的开始或者结束部分,不匹配任何的字符。
^(开头) 在[]内代表非 在模式串的开头代表第一个字母是什么
$ 末尾
*/
public class Demo4 {
public static void main(String[] args) {
System.out.println("hello world".matches("hello\\bworld")); //false
System.out.println("hello world".matches("hello\\b world"));
p("hello sir".matches("^h.*"));//开头必须是h后面匹配多个0次或多个字符
p("adasdasd".matches("a.*")); //a后面匹配多个0次或多个字符
p("adasdasd".matches(".*")); //这是任意的0个或多个字符
p("adasdasd".matches("a*"));//a后面是0个或多个a flase
p("hello sir".matches(".*ir$"));
p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));
p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));
//空白行
p(" \n".matches("^[\\s&&[^\\n]]*\\n$"));
//第一个事空格,一个或多个,末尾是\n
//练习
p("aaa 8888c".matches(".*\\d{4}.")); //true
p("aaa 8888c".matches(".*\\b\\d{4}."));//true
p("aaa 8888c".matches(".*\\d{4}."));//true
p("aaa8888c".matches(".*\\b\\d{4}."));//false
//邮箱的匹配
p("nianxiongdi321@163.com".matches("[a-zA-Z|[0-9]]+@[a-zA-Z|[0-9]]+.[a-zA-Z]{1,6}"));
p("nianxiongdi321@163.com".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+")); //[]中的-代表字符
}
private static void p(boolean matches) {
System.out.println(matches);
}
}
package cn.itcast.exp;
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;
//统计某网站的email地址,可以发垃圾邮件
//Spider-- 这种程序蜘蛛程序
public class Demo5{
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("E:\\myeclipes\\RegExp\\src\\file\\回复:【坐等更新。。。。谁要1__464 。 留Email 】_王爷要休妃吧_百度贴吧.html"));
String line = "";
while((line=br.readLine())!=null){
parse(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void parse(String line) {
Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
Matcher m = p.matcher(line);
while(m.find()){
System.out.println(m.group());
}
}
}
package cn.itcast.exp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//Greedy Reluctant Possessive区别
public class Demo6 {
public static void main(String[] args) {
/*//Greedy (.{3,10})[0-9] -->一般使用这个
//先把s吞取10个字符再说,与模式串进行匹配,匹配失败,把最后一个吐出来,吐出来的正好是数字,正好匹配,所以输出0-10
Pattern p = Pattern.compile("(.{3,10})[0-9]");
String s = "aaaa3bbbb6";
Matcher m = p.matcher(s);
if(m.find()){
p(m.start()+ "-" + m.end());
}else{
p("not match");
}*/
/*//Reluctant (.{3,10}?)[0-9]
//这个与Greedy正好相反 吞最少的 正好结果为0-5
Pattern p = Pattern.compile("(.{3,10}?)[0-9]");
String s = "aaaa3bbbb6";
Matcher m = p.matcher(s);
if(m.find()){
p(m.start()+ "-" + m.end());
}else{
p("not match");
}*/
// Possessive 与Greedy 不同的是,它不吐字符,这个匹配不上
Pattern p = Pattern.compile("(.{3,10}+)[0-9]");
String s = "aaaa3bbbb6";
Matcher m = p.matcher(s);
if(m.find()){
p(m.start()+ "-" + m.end());
}else{
p("not match");
}
}
private static void p(Object o) {
System.out.println(o);
}
}
package cn.itcast.exp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//代码统计小程序
public class CodeCounter {
static long normaLines = 0;//正常的行数
static long commentLines = 0;//注释行数
static long whiteLines = 0;//空白行
public static void main(String[] args) {
File f = new File("E:\\SQF\\BaiduYunDownload\\尚学堂\\马士兵Java\\尚学堂科技_马士兵_JAVASE_坦克大战网络版\\尚学堂科技_马士兵_JAVA_坦克大战网络版视频教程\\source\\TankWar1.9.11\\src");
File[] codeFiles = f.listFiles();//获取文件呢
//.java结尾的文件检索
for(File code:codeFiles){
if(code.getName().matches(".*\\.java$")){//后缀.java文件
parse(code);
}
}
System.out.println("normaLines:" +normaLines );
System.out.println("commentLines:" + commentLines);
System.out.println("whiteLines:" +whiteLines );
}
private static void parse(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();//注意去空格,不要在36行去空格,空行时候
//readLine在读取数据的时候,会把每一行的\n去掉
if(line.matches("[\\s&&[^\\n]]*$")){//空行的处理 在不用readLine处理空行-----> [\\s&&[^\\n]]*\n$
whiteLines++;
}else if(line.startsWith("/*")&&line.endsWith("*/")){ //当多行注释在一行的时候
commentLines++;
}else if(line.startsWith("/*")&&!line.endsWith("*/")){//当多行注释不再一行的时候
commentLines++;
comment = true;
}else if(true == comment){ //多行注释的中间的进行统计
commentLines++;
if(line.startsWith("*/")){//当统计到多行注释的最后一行把comment置为false
comment = false;
}
}else if(line.startsWith("//")){ //单行注释
commentLines++;
}else{//代码行统计
normaLines++;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}