------- android培训、java培训、期待与您交流! ----------
正则表达式:符合一定规则的表达式。
* 作用:专门操作字符串的规则。对字符串进行操作既便捷又简单的方式。
* 特点:用一些特定的符号来表示代码操作。
* 好处:这样就简化了书写。
* 弊端:符号定义越多,正则越长,阅读性越差。
正则表达式常见的操作:
* 1.匹配:通过String类的matches(String regex) 方法。用规则匹配整个字符串,只要有一处不符合规则,那么匹配就结束。返回false。
*
* 2.切割:String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
*
* 3.替换:String replaceAll(String regex, String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
* 4.获取:将字符串中符合规则的子串取出来。
1. 匹配:
匹配用的最多的地方就是验证,比如说验证QQ号,验证邮箱,验证手机号码等等。假如说没有正则表达式的话,用普通的String类的方法也是可以验证的,但是普通的方法往往需要很多层的判断,代码书写量过多,阅读性不佳。例如,想要校验一个QQ号码,要求:5-15位,不能以0开头,只能是数字。我们需要进行多层判断。
代码如下:
/* 通过String方法组合校验QQ的方法。
* 以下的这种校验方式使用String类中的方法进行组合,没有使用正则表达式。虽然完成了需求,但是代码太过复杂,阅读性不佳。
* */
public static void checkQQByStringMethod()
{
//定义一个QQ号的字符串
String qq = "446366628";
//获取QQ号字符串的字符长度
int len = qq.length();
//判断长度,如果长度不为0,即不为空,才执行if里面的语句。
if (!(len == 0))
{
//字符串长度不为0,则判断这个if里面条件,要满足字符串长度为5-15之间。
if (len >= 5 && len <= 15)
{
//若满足上一个if条件,则执行这个if判断。若果QQ号码不是以0开头,则进入这个if下的语句。
if (!qq.startsWith("0"))
{
try
{
//把QQ号码的字符串转换为Long整型,若QQ号码中包含了不能转换为Long整型的字符,那么这个方法会抛出
//NumberFormatException 数字格式异常。就是说如果QQ号正确的话则不会抛出异常。
Long lo = Long.parseLong(qq);
//QQ号正确的话则不会抛出异常,就执行打印提示信息和QQ号码。
System.out.println("您的QQ号码为:"+lo);
}
//若抛出异常,就是说有不能转换成整型的字符。则处理异常
catch (NumberFormatException e)
{
//处理结果为:打印提示信息 这不是QQ号码! 由此一个QQ号码才算校验完毕!!!
System.out.println("这不是QQ号码!");
}
//若不用上述的parseLong抛出异常的方法校验QQ号码是否全部为数字字符,则可以用一下方法校验。
//把QQ号码字符串转换成字符数组
// char[] arr = qq.toCharArray();
//
//定义标记
// boolean flag = true;
//循环遍历字符数组中的每个字符
// for (int x = 0; x < arr.length; x++)
// {
//若遍历到不是 0-9 之间的数字字符,则执行这个if下面的操作
// if (!(arr[x] > '0' && arr[x] < '9'))
// {
//把标记改为 false 并跳出循环,因为一旦遇到不符合要求的字符,就不需要对后面的字符再进行校验了
// flag = false;
// break;
// }
// }
//若QQ号码正确,flag会始终为 true 则 输出提示信息和 QQ号码
// if (flag)
// sop("QQ为;"+qq);
//若一旦遇到不符合要求的字符,flag就被改为了false 那么,就打印提示 这不是一个QQ!
// else
// sop("这不是一个QQ!");
}
//这个else 是何上面 if (!qq.startsWith("0")) 为一个整体,如果QQ号码是以0开头,则执行这个else下语句。
//打印 不能以 0 开头 提示信息。
else
sop("不能以0开头!");
}
//这个else是和上面 if (len >= 5 && len <= 15) 为一个整体,若QQ号码长度不在5-15之间,则执行这个else下的语句
//提示字符串长度错误!
else
sop("字符串长度错误!");
}
//否则,打印输入为空的提示信息。
//这个 else 语句和 上面 if (!(len == 0)) 是一个整体,如果QQ号字符串字符长度为0,则执行这个else的语句。
else
sop("输入为空!");
}
普通验证的过程相对正则表达式来说较为复杂,而且多重判断会降低程序的运行效率。而正则表达式就是来解决这类问题的。同样的是校验QQ号码,用正则表达式来校验就要相对简单得多,代码相对简洁,便于阅读。
代码示例:
//1.正则表达式之匹配:通过正则表达式校验QQ号码方法
public static void checkQQByRegex()
{
//定义一个QQ号的字符串表现形式
String qq = "446366628";
//定义规则, "[1-9][0-9]{4,14}" 该规则表示第一位必须是1-9之间其中任何一位整数,后面必须是 4-14 位 0-9之间的整数
String regex = "[1-9][0-9]{4,14}";
//调用String类的matches方法,把定义好的字符串和定义好的规则进行匹配,返回boolean型的值
boolean flag = qq.matches(regex);
//如果匹配成功,打印您的QQ号
if (flag)
sop("您的QQ是:"+qq);
//如果匹配失败,打印错误提示信息
else
sop("输入的号码不正确!");
}
由此可见正则表达式处理这类问题的过程相对普通的String方法要简单得多,代码只有几句,便于书写,提高了阅读性。
2.切割:
String[] split(Stringregex) 根据给定正则表达式的匹配拆分此字符串。
假如我们需要把一个长字符串里面的内容用某个符号或字母切割开形成一系列的子字符串,那么可以用切割来做。
代码示例:
//2.正则表达式之切割 String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
public class RegexSplit
{
public static void main(String[] args)
{
//:切割字符串。调用切割函数,传入指定字符串,用(" +") 用一次或多次空格 来切割
splitDemo("Jack Mike Piter Marry Rose", " +");
//调用打印分割线功能
printHr();
//2.正则表达式之切割:切割字符串。调用切割函数,传入指定字符串,
//切割规则为("\\.")用 (.) 切割。因为 (.) 本来属于正则表达式里面的特殊符号,所要要用转义字符
splitDemo("Jack.Mike.Piter.Marry.Rose", "\\.");
printHr();
//2.正则表达式之切割:切割字符串。调用切割函数,传入指定字符串,用(\\)要加两个转义字符 (\\)
splitDemo("C:\\abc\\a.txt", "\\\\");
printHr();
//2.正则表达式之切割:切割字符串。调用切割函数,传入指定字符串,按照叠词进行切割。
//组:(.)\n n表示要使用和第n组同样的规则,比如n为1的话,就表示第二位使用和第一位同样的规则。封装成字符串的话要转义.
//加号表示第二位的规则出现一次或多次。
//为了可以让规则被重用,可以将规则封装成一个组,用 () 来完成,组的出现都有编号,从1开始,想要使用已有的组可以通过 \n
//的形式获取。n就是组的编号
splitDemo("Izzwantyytoxxenteraathebbdarkcchorsedd", "(.)\\1+");
printHr();
}
//2.正则表达式之切割:切割字符串
public static void splitDemo(String str, String regex)
{
//定义一个字符串
// String str = "Jack.Mike.Piter.Marry.Rose";
//定义切割正则表达式规则, (" +") 用一次或多次空格 来切割
// String regex = " +";
//定义切割正则表达式规则, ("\\.")用 (.) 切割。因为 (.) 本来属于正则表达式里面的特殊符号,所要要用转义字符
// String regex = "\\.";
//使用split方法,把需要切割的字符串按照定义好的切割规则来进行切割,得到的是字符串数组。
String[] arr = str.split(regex);
//循环遍历数组,打印数组每个角标对应的字符串
for (String name : arr)
System.out.println(name);
}
//打印分割线功能
public static void printHr()
{
System.out.println("-----------------------");
}
}
3. 替换:
String replaceAll(String regex,String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
代码示例:
public class RegexReplaceAll
{
public static void main(String[] args)
{
//3.正则表达式之替换:定义一个字符串,将电话号码和QQ号码换成#符号
String str = "I want13477663122to enter446366628 the dark horse programmer";
//调用正则表达式替换字符串函数,将指定的字符串,用指定的替换规则 "\\d{9,11}" 若0-9出现了9-11次的话,就把它替换成 #符号
replaceAllDemo(str, "\\d{9,11}","#");
//调用打印分割线功能
printHr();
//3.正则表达式之替换:定义一个字符串,将叠词换成@符号
String str1 = "Izzwantyytoxxenteraathebbdarkccccccchorsedd";
//调用正则表达式替换字符串函数,将指定的字符串,用指定的替换规则 "(.)\\1+" 若出现了两次或者多次的任意同一符号,就把它替换成@符号
replaceAllDemo(str1, "(.)\\1+", "@");
printHr();
//3.正则表达式之替换:定义一个字符串,将重叠的字母变与之相同的单个字母
String str2 = "Izzwantyytoxxenteraathebbdarkccccccchorsedd";
//调用正则表达式替换字符串函数,将指定的字符串,用指定的替换规则,"(.)\\1+" 若出现了两次或者多次的任意同一符号,
// 就把它替换成 "$1" 表示,替换规则里的第一组规则里的字母。
replaceAllDemo(str2, "(.)\\1+", "$1");
printHr();
}
//3.正则表达式之替换:正则表达式替换字符串功能
public static void replaceAllDemo(String str, String regex, String newStr)
{
//用String类的replaceAll方法。把str变量中的字符串中符合 regex 参数规则的子字符串替换成newStr参数字符串
str = str.replaceAll(regex, newStr);
//打印替换后的结果
System.out.println(str);
}
//打印分割线
public static void printHr()
{
System.out.println("------------------------------");
}
}
4.获取:将字符串中符合规则的子串取出来。
*操作步骤:
* 1.将正则表达式封装成对象。
* 2.让正则对象和要操作的字符串相关联。
* 3.关联后获取正则匹配引擎
* 4.通过引擎对符合规则的字符串进行操作,比如取出。
代码示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexGet
{
public static void main(String[] args)
{
//4.正则表达式之获取:调用根据正则表达式获取需要的字符串函数
getDemo();
}
//4.正则表达式之获取:根据正则表达式获取需要的字符串函数
public static void getDemo()
{
// String str = "446366628";
// String regex = "[1-9]\\d{4,14}";
//定义一个字符串
String str = "ming tian jiu yao fang jia le, da jia";
//定义要操作字符串的规则
String regex = "\\b[a-z]{4}\\b";
//将规则封装成正则对象。
Pattern pat = Pattern.compile(regex);
//让正则对象和要被作用的字符串相关联,获取匹配器对象。也可以称之为匹配引擎。
Matcher mat = pat.matcher(str);
//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的,
//只不过被String的方法封装后,用起来较为简单,但是功能却单一。
// sop(mat.matches());
//将规则作用到字符串上,并进行符合规则的子串查找。
while(mat.find())
{
//获取匹配后的结果
sop(mat.group());
//获取符合正则表达式规则的子字符串的开始索引和结束位置索引
sop(mat.start()+"---"+mat.end());
}
//按照定义好的规则去切割字符串,存入字符串数组
String[] arr = str.split(regex);
//循环打印被切割后的字符串结果
for (String str1 : arr)
sop(str1);
}
//打印功能
public static void sop(Object obj)
{
System.out.println(obj);
}
}
网页爬虫小案例:
网页爬虫可以抓取到网页上,或者是计算机文档中,我们所需要的一些特定的信息。比如说,一个网页上有很多别人留下的邮箱地址,我们需要获取网页上所有的邮箱地址,然后利用这些邮箱地址,给他们发送广告,我们就可以用到网页爬虫去爬我们需要的邮箱地址了。
代码示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WebSpiders
{
public static void main(String[] args) throws Exception
{
//调用获取硬盘上一个文档中的邮箱地址功能
getMails();
//打印分割线,在控制台上在两个函数的打印结果之间加一条分割线,提高阅读性
printHr();
//调用获取指定网页上的邮箱地址功能
getMailByWeb();
}
/* 获取指定文档中的所有邮件地址。使用正则表达式的获取功能。
* */
public static void getMails() throws Exception
{
//创建一个文件读取流对象,关联要读取的文件。并加入缓冲技术
BufferedReader bufrIn = new BufferedReader(new FileReader("mailDocument.txt"));
//定义获取字符串的正则表达式规则
String regex = "\\w+@\\w+(\\.\\w+)+";
//把定义好的正则表达式规则封装成正则对象
Pattern pat = Pattern.compile(regex);
//定义一个匹配器对象
Matcher mat = null;
//目的打印流,里面封装了文件输出流对象。用于把获取到的需要的数据写入本地硬盘的一个文件中
PrintWriter pwOut = new PrintWriter(new FileWriter("getMails.txt"), true);
//line变量用来记录从文件中读取到的字符串
String line = null;
//一行一行的循环读取文档中的数据,并用line变量记录
while ((line = bufrIn.readLine()) != null)
{
//让正则对象和读取到一行的字符串相关联,获取到匹配引擎
mat = pat.matcher(line);
//循环查找读到的一行字符串里有没有和正则对象里的规则向匹配的字符串子串
while (mat.find())
{
//若有,则获取这个子串,并用mail变量记录
String mail = mat.group();
//打印获取到的需要的字符串到控制台
sop(mail);
//把获取到的需要的字符串写入目的打印流中,存入硬盘上的一个文档中
pwOut.println(mail);
}
}
//关闭读取流资源
bufrIn.close();
//关闭输出流资源
pwOut.close();
}
//把一个网页上的邮箱地址获取到,打印到控制台。并存入硬盘上的一个文档中。
public static void getMailByWeb() throws IOException
{
//创建URL对象,指定要访问的主机,端口,资源路径,和资源。
URL url = new URL("http://192.168.1.101:8080//myweb//mails.html");
//获取这个URL对象的连接对象,可以打开指定的连接
URLConnection urlcon = url.openConnection();
//获取客户端输入流,并封装成字符读取流。用来读取服务端发过来的网页数据的字符串表现形式
BufferedReader bufrIn =
new BufferedReader(new InputStreamReader(urlcon.getInputStream()));
//定义需要获取的字符串的匹配规则
String regex = "\\w+@\\w+(\\.\\w+)+";
//把定义好的匹配规则封装成正则对象
Pattern pat = Pattern.compile(regex);
//定义一个匹配器对象
Matcher mat = null;
//创建一个目的打印流,里面封装了文件输出流。用来把从服务端发来数据读取后,获取到需要的邮箱再存入到本地硬盘的一个文档中
PrintWriter pwOut = new PrintWriter(new FileWriter("webMails.txt"), true);
//line变量用来记录从服务端发来数据的字符串表现形式
String line = null;
//一行一行循环读取从服务端发来数据的字符串表现形式,并用line变量记录
while ((line = bufrIn.readLine()) != null)
{
//把定义好的正则对象和要被作用的从服务端读取到的数据字符串相关联,获取匹配器。
mat = pat.matcher(line);
//循环查找每一行是否有符合匹配规则的字符串
while (mat.find())
{
//如果有就打印到控制台
sop(mat.group());
//并且用目的打印流写入硬盘上的文档中
pwOut.println(mat.group());
}
}
//关闭读取流资源
bufrIn.close();
//关闭目的打印流资源
pwOut.close();
}
//打印字符到控制台的功能
public static void sop(Object obj)
{
System.out.println(obj);
}
//打印分割线功能
public static void printHr()
{
System.out.println("-------------------------------------------");
}
}
------- android培训、 java培训、期待与您交流! ----------