一,正则表达式简介及四种具体操作功能:匹配,切割,替换,获取
package fighting;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
/**
* 正则表达式:符合一定规则的表达式。
* 作用:专门用于操作字符串
* 特点:用一些特定的符号来表示一些代码操作,这样就简化书写。
* 学习正则表达式就是在学习一些特殊符号的使用
* 注意哦:String类的方法matches可以查看正则表达式的写法。
* 好处:可以简化对字符串的复杂操作。
* 弊端:符号定义越多,正则越长,阅读性越差
*
* 具体操作功能:
* 1,匹配:String matches()方法
* 返回true和false
* 2,切割:String split()
* 把规则外的取出
* 3,替换:String replaceAll()
* 返回替换后的字符串
* 4,获取:将字符串中符合规则的子串取出
*
* 获取的操作步骤:1.将正则表达式封装成对象。
* 2.让正则对象和要操作的字符串相关联
* 3.关联后,获取正则匹配引擎
* 4.通过引擎对符合规则的子串进行操作,比如取出。
* 关于获取的一个小知识点:
* 获取时用到的匹配器Matcher,它的两个方法matches和find都是返回匹配结果true或false。
* matches():是整个字符串与正则表达式去匹配
* find():尝试查找与该模式匹配的输入序列的下一个子序列,
* 即从字符串中查找有没有与正则表达式匹配的子序列。
*/
public static void main(String[] args) {
myMatches();
mySplit();
myReplaceAll();
myFetch();
}
//获取的讲解
public static void myFetch(){
String str="ming tian jiu yao fang jia le,da jia.";
String reg="[a-z]{3,}\\b";//\b是单词边界
//1,将正则表达式封装成对象
Pattern p =Pattern.compile(reg);
//2,让正则对象和要作用的字符串相关联
Matcher m = p.matcher(str);
System.out.println("matches:"+m.matches());//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的,
//但是String类封装后,用起来虽然较为简单,但功能单一。
// boolean b =m.find();//将规则作用到字符串上,并进行符合规则的子串查找
// System.out.println(m.group());
//由于匹配器Matcher已经匹配过一次,所以索引已经到了5,再执行find方法,会从索引5处进行匹配,
//结果就导致下面的输出结果中缺少了前4个字符ming
while(m.find()){
System.out.println(m.group());
}
}
//替换的讲解
public static void myReplaceAll(){
//将字符串的数字替换成#
String str="war13899330000ty123455auto1244324f";
String reg="\\d{5,}";
str =str.replaceAll(reg,"#");
System.out.println(str);
//将叠词替换成#
String str1="arkkgyqquizzc";
String reg1="(.)\\1+";
str1=str1.replaceAll(reg1, "#");
System.out.println(str1);
//将重叠的字符替换成当字符:zzzz->z
String str2="arkkgyqquizzc";
String reg2="(.)\\1+";
str2=str2.replaceAll(reg2, "$1");//$1是可以取出前一个规则中的第一组
System.out.println(str2);
}
//切割的讲解
public static void mySplit(){
//逗号的切割
String str = "zhangsan,lisi,wagnwu";
String reg=",";
String[] arr =str.split(reg);
for(String s:arr){
System.out.println(s);
}
//若干空格的切割
String str1 ="zhangsan lisi wagnwu";
String reg1=" +";
String[] arr1 =str1.split(reg1);
for(String s:arr1){
System.out.println(s);
}
//点.的切割
String str2="zhangsan.lisi.wagnwu";
String reg2="\\.";//在正则表达式中,.匹配任意字符,\.才是争取表达式中的.,\\.才是正确的正则表达式
String[] arr2 =str2.split(reg2);
for(String s:arr2){
System.out.println(s);
}
//切割双斜杠
String str3="C:\\abc\\a.txt";
String reg3="\\\\";
String[] arr3 =str3.split(reg3);
for(String s:arr3){
System.out.println(s);
}
/**
* 为了可以让规则的结果被重用,可以将规则封装成一个组,
* 用()完成,组的出线都有编号,从1开始,想要使用已有的组可以通过\n(n就是组的编号)的形式来获取
*/
//切割叠词,组:用()封装起来为一个组。
String str4="arkkgyqquizzc";
String reg4="(.)\\1+";//第一位为任意字符,第一位的内容在第二位又出现了,\1是引用第一组的结果,+代表不只一个和第一组相同
String[] arr4 =str4.split(reg4);
for(String s:arr4){
System.out.println(s);
}
}
//匹配的讲解
public static void myMatches(){
//1,匹配
String str = "ba";
String reg = "[bcd][a-z]";//第一个字母是b、c、d中的一个,第二个字母是小写字母
String reg1 ="[^bcd]";//第一个字母是bcd以外的字母,并且这个字符串只能有一个字符
System.out.println(str.matches(reg));//true
System.out.println(str.matches(reg1));//false
String str2="b9a";
String reg3 = "[a-zA-Z][0-9]";//第一个是字母,第二个是数字
System.out.println(str2.matches(reg3));//false reg3只能校验长度为2的字符串
//注意:正则表达式当中,反斜杠一定是成对出现的
String reg4 ="[a-zA-Z]\\d[a-z]";//\d匹配任意数字,等价于[0-9]
System.out.println(str2.matches(reg4));//true
//字符串长度不固定的情况
String str3="b32";
String reg5="[a-z]\\d*";//第一位是字母,后面是0或多个数字
System.out.println(str3.matches(reg5));//true
System.out.println(str.matches(reg5));//false
System.out.println(str2.matches(reg5));//false
String reg6 = "[a-z]\\d{2}";//第一位是字母,后面恰好两位数字
System.out.println(str3.matches(reg6));//true
String str4="b123";
String str5="b1";
String reg7 = "[a-z]\\d{2,}";//第一位是字母,后面至少两个数字
System.out.println(str3.matches(reg7));//true
System.out.println(str4.matches(reg7));//true
System.out.println(str5.matches(reg7));//false
//具体事例:匹配手机号段;13xxx,15xxx,18xxx
String telephone = "13900001111";
String telReg="1[358]\\d{9}";
System.out.println("手机号码有误吗?"+telephone.matches(telReg));
}
}
二,利用正则表达式的一个小例子:去重复
package fighting;
public class RegexDemo2 {
/**
* 需求:将下列字符串转成:我要学编程
*
* 应该使用四种功能中的哪个或哪几个呢?
* 1,如果只想知道该字符串是否对与错,使用匹配
* 2,想要将已有的字符串编程另一个字符串,替换
* 3,想要按照自定义的方式将字符串变成多个字符串,切割。获取规则意外的子串
* 4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串
*/
public static void main(String[] args) {
String str="我我...我我...我要...要要...要要...学学学....学学..编编编.....编程..程..程";
/**
* 将已有字符串编程另一个字符串。使用替换
* 1,可以先将.去掉
* 2,再去重复
*/
String reg="\\.+";
// String reg="\\.{1,}";//这样写结果也是对的
str=str.replaceAll(reg, "");
System.out.println(str);//我我我我我要要要要要学学学学学编编编编程程程
System.out.println(str.replaceAll("(.)\\1+", "$1"));//我要学编程
}
}
三,将ip地址进行地址段顺序的排序,主要用到替换和切割
package fighting;
import java.util.TreeSet;
public class RegexDemo3 {
/**
* 将ip地址进行地址段顺序的排序
* 192.68.1.254 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30
*/
public static void main(String[] args) {
/**
* 还按照字符串自然顺序,只要让他们每一段都是3位即可
* 1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位
* 2,将每一段只保留3位。这样,所有的ip地址都是每一段3位
*/
String ip="192.68.1.254 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";
ip=ip.replaceAll("(\\d+)", "00$1");//一个或多个数字,在前面补两个0
System.out.println(ip);//00192.0068.001.00254 00102.0049.0023.0013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
ip=ip.replaceAll("0*(\\d{3})", "$1");//以0开头的数字,只保留后三位数字,这是因为10和2,如果进行排序的话,10应该在前面,所以要补全3位进行判断
System.out.println(ip);//192.068.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
String[] arr = ip.split(" +");//按照一个或者多个空格分隔
TreeSet<String> ts = new TreeSet<String>();
for(String s:arr){
ts.add(s);//分隔的字符串存储到集合中
}
for(String s:ts){
System.out.println(s.replaceAll("0*(\\d+)", "$1"));//去掉开始的0打印输出
}
}
}
四,利用正则表达式对邮箱地址进行校验的两种方法;
package fighting;
public class RegexDemo4 {
/**
* 需求:对邮箱地址进行校验
*/
public static void main(String[] args) {
String mail="abc12@sina.com.cn.cn";
//较为精确的匹配
boolean b = mail.matches("[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+");
System.out.println(b);
//笼统的匹配
b= mail.matches("\\w+@\\w+(\\.\\w+)+");
System.out.println(b);
}
}
五,网页爬虫:获取网络上的一些信息:这里实现获取网页上的邮箱地址
package fighting;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo5 {
/**
* 网页爬虫(蜘蛛)
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//从文件中国获取邮箱地址
getMails_1();
//从网页中获取邮箱地址
getMails_2();
}
private static void getMails_2() throws Exception {
URL url=new URL("http://zhidao.baidu.com/question/452826499.html");
URLConnection conn = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Pattern p = Pattern.compile("\\w+@\\w+(\\.\\w+)+");
String line = null;
while((line = br.readLine())!=null){
Matcher m =p.matcher(line);
while(m.find()){
System.out.println(m.group());
}
}
}
//获取指定文档中的邮件地址,获取功能 Pattern Matcher
public static void getMails_1() throws Exception{
BufferedReader br = new BufferedReader(new FileReader("src/server.txt"));
Pattern p = Pattern.compile("\\w+@\\w+(\\.\\w+)+");
String line=null;
while((line = br.readLine())!=null){
Matcher m =p.matcher(line);
while(m.find()){
System.out.println(m.group());
}
}
}
}