黑马程序员Java正则表达式
正则表达式
概述:
正则表达式:符合一定规则的表达式
作用:
用于专门操作字符串,描述共享该模式的一组字符串。
在java中有String类专门操作字符串为什么还要正则表达式呢?
因为这些功能太简单,组合起来功能代码太多
特点:
用于一些特定符号来表示一些代码操作。这样就简化了书写。
所以学习正则表达式就是在学习一些特殊符号的使用
弊端:
符号定义的愈多,正则表达式越长所以阅读性越差
常见特殊符号:
字符:
X 字符x
\\ 反斜线字符
\t 制表符
\n 换行符
\r 回车符
\f 换页符
\e 转义符
字符类
[abc] a,b或c(简单类)
[^abc] 除了abc的任何字符
[a-d[m-p]] a到d或m到p即取并集
[a-z&&[def]] d,e,f即取交集
[a-z&&[^bc]] 取的是a到z,减去b和c
[a-z&&[^m-p]] 取的是a到z,减去m到p
预定义字符类
. 任何字符
\d 数字:[0-9]
\D 非数字:[^0-9]
\s 空白字符:[\t\n\xOB\f\r]
\S 非空白字符:[^\s]
\w 单词字符[a-zA-Z_0-9]
\W 非单词字符[^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符
\z 输入的结尾
Greedy数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好N次
X{n,} X,至少n次
X{n,m} X,至少n次,但不超过m次
具体操作功能:
1, 匹配:
在String类中方法boolean String matches()//告知此字符串是否匹配给定的正则表达式
示例:
要求输入5~15位的qq号码,要求0不能开且只能是数字。
Import java.util.regex;
class QQDemo{
public static void main(String[] args) {
String qq = "1323wr55424";
//方式三:利用正则表达式来实现
String regex = “[1-9]\\d{4-14}”;//第一位范围是1到9的数字,第二位或到第十五位的必须是0到9的数字
//用String类里的matches()判断是否符合规范
if(qq.macthes(regex)){
System.out.println(qq);
}
else{
System.out.println(“你输入的字符非法”);
}
/*int len = qq.length();
if (len>=5&&len<=15){
if (!qq.startsWith("0")){
//方式二:利用封装基本数据类型出现的非数字报异常特点,但是方法不易想到
try{
long l = Long.paseLong(qq);
}
catch (NumberFormatException e){
System.out.println("输入的字符非法);
}*/
/*方式一:依次判断,但是速度慢效率低代码臃肿
char[] ch = qq.toCharArray();
boolean flag = true;
for (int x=0;x<=ch.length ;x++ ){
if (!(ch[x]>'0'&&ch[x]<='9')){
flag = false;
break;
}
}
if (flag){
System.out.println(qq);
}
else{
System.out.println("输入的字符非法");
}
}
else{
System.out.println("不能以0开头");
}
}
else{
System.out.println("你输入的长度非法");
}
}*/
}
示例二:
import java.util.regex.*;
class Demo{
public static void main(String[] args) {
//匹配手机号段
//13xxx 15xxx 18xxx
String haoma = "13837659876";
String regex = "1[358]\\d{9}";
if (haoma.matches(regex)){
System.out.println(haoma);
}
else{
System.out.println("手机号非法");
}
}
}
2,切割:
String类中的String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
示例:
import java.util.regex.*;
class Demo{
public static void main(String[] args) {
//复杂切割,如“张三 李四 王五 周期”,之间空格不确定数
//这时可以用"空格+"即多个空格来切
splitDemo("张三 李四 王五 周期"," +");
//注意不能用“.”直接切,他是个特殊符号。需用\\.来切
splitDemo("张三.李四.王五.周期","\\.");
/*切割叠词切叠词多少不限,这时需要用到组,(.)\\1+;
按照叠词切割可以让规则的结果被重用,可以将规则封装成一个组,
用()完成。组的出现都有编号,从1开始,想要使用已有的组可以通过
\n(n就是组的编号)的形式来获取
*/
splitDemo("errruyuuuussytcd","(.)\\1+");
}
public static void splitDemo(String str,String reg){
String[] names = str.split(reg);
for(String name:names){
System.out.println(name);
}
}
}
3,替换:
String类中的String replaceAll(String regex,String replacement)
示例:
import java.util.regex.*;
class Demo{
public static void main(String[] args) {
String replace1 = "shjgdhhawujjjjlaiw";//将重复的字符替换成#。
String replace3 = "shjg234132535dhhawuj11242353532jjjla34iw";//将连续5个以上的数字替换成#。
String replace2 = "shjgdhhawujjjjlaiw";//将重复的字符替换成单个,通过$来获取组的元素
replaceAll(replace1,"(.)\\1+","#");
replaceAll(replace3,"\\d{5,}","#");
replaceAll(replace2,"(.)\\1+","$1");
public static void replaceAll(String str,String reg,String newstr){
String str1 = str.replaceAll(reg,newstr);
System.out.println(str1);
}
}
获取:
将字符串中的符合规则的子串取出。
操作步骤:
1, 将正则表达式封装成对象
2, 让正则对象和要操作的字符串相关连
3, 关联后,获取正则匹配引擎。
4, 通过引擎对符合规则的子串进行操作,比如取出。
查询API在java.Util.regex中有Pattern类
正则表达式的编译表示形式,指定为字符串的正则表达式必须首先被编译为此类的实例
因为该类没有构造函数,可以通过类中的方法获取此类对象。
Static Pattern compile(String regex);//将给定的正则表达式编译到模式中
Matcher matcher(CharSequence input);//创建匹配给定的输入与此模式的匹配器
Mactcher类引擎或匹配器,通过解释Pattern,执行匹配操作的引擎。
Macther类中的常用方法:
Boolean find();//尝试查找与该模式匹配的输入序列的下一个子序列
String group();//返回有以前匹配操作所匹配的输入子序列。
说明:
其实String类中的matchers方法,用的就是Pattern和Macther对象来完成的,
只不过被String的方法封装后,用起来简单且功能也单一。
示例:
import java.util.regex.*;
class Demo2{
public static void main(String[] args) {
getDemo();
}
public static void getDemo(){
String str = "jin tian jiu shi di er shi wu tian";
String reg = "\\b[a-z]{3}\\b";//匹配规则,获取三个字母组成的单词.同时还需用到单词边界匹配器\b
//将规则封装成对象
Pattern p = Pattern.compile(reg);
//让正则对象和要作用的字符串相关联,获取匹配器对象。
Matcher m = p.matcher(str);
//将规则作用到字符串上并进行符合规则的子串查找
//boolean b = m.find();找到返回true,反之false;
//System.out.println(b);
//获取匹配后的结果,通过while循环,打印出来
while (m.find()){
System.out.println(m.group());
}
}
}
对于这四种功能什么时候该用哪一个呢?或者那几个呢?
1, 如果只想知道该字符串是否对或错,就使用匹配macthes
2, 想要将已有的字符串编程另一个字符串,使用替换,replaceAll
3, 想要按照自定的方式将字符串变成多个字符串,就用切割split来获取规则以外的子串
4, 想要拿到符合需求的字符子串,就用获取,获取符合规则的子串。
练习一:
/*
需求:将下面的字符串转换成“我要学编程”
我我...要要要要......学学..编编........程程
*/
class Demo3{
public static void main(String[] args) {
String str = "我我...要要要要......学学..编编........程程";
//先将“..”替换
str = str.replaceAll("\\.+","");
//再将多个重复内容变成单个
str = str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
/*
需求:
将ip地址进行地址段顺序的排序。
192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.301
分析步骤:
1,先将所有数前面添0补足最低三位
2,将前三位是0的替换
3,切割空格
4,再将其排序
*/
import java.util.*;
class Demo4{
public static void main(String[] args) {
String str =
"192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.301";
str = str.replaceAll("(\\d+)","00$1");//至少保证每段都有三位
System.out.println(str);
str = str.replaceAll("0*(\\d{3})","$1");//保证每段只有三位
System.out.println(str);
String[] s = str.split(" ");//按照空格切割
/*
TreeSet<String> ts = new TreeSet<String>();//把字符数组的元素添加进集合
for(String ss:s){
ts.add(ss);
}
//从集合取出元素
for(String s1:ts){
System.out.println(s1.replaceAll("0*(\\d+)","$1"));//将面多余的0去电
}
*/
Arrays.sort(s);//对数组元素进行排序
//取出元素
for(String s1:s){
System.out.println(s1.replaceAll("0*(\\d+)","$1"));//将面多余的0去电
}
}
}
练习三:
/*
需求:对邮件地址进行校验
*/
class Demo5{
public static void main(String[] args) {
String mail = "9823hg@as.com.cn";
//较为精确匹配
String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
//简单匹配
//String reg = "\w+@\w+(\\.\\w+)+";
System.out.println(mail.matches(reg));
}
}
网页爬虫
用于收索网络上的指定信息,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本
例如:邮箱等。
代码示例:
import java.io.*;
import java.util.regex.*;
import java.net.*;
class Demo6{
public static void main(String[] args) throws Exception{
getMail_1();//需求:收集指定文件里的邮箱信息
getMail_2();//需求:获取指定网页中的mail信息,并打印控制台
}
public static void getMail_1()throws Exception{
//关联文件
BufferedReader br =
new BufferedReader(new FileReader("mail.txt"));
String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
//把规则封装成对象
Pattern p = Pattern.compile(reg);
//将数据读取出来
String mail = null;
while ((mail=br.readLine())!=null){
//让正则对象和要作用的字符串相关联,获取匹配器对象。
Matcher m =p.matcher(mail);
while (m.find())//判断是否匹配{
System.out.println(m.group());
}
}
}
public static void getMail_2()throws Exception{
//对网页地址进行封装
URL u = new URL("http://bbs.itheima.com/thread-98858-1-1.html");
//连接服务器
URLConnection uc = u.openConnection();
//获取网络读取流,对服务器上的信息进行读取
BufferedReader br =
new BufferedReader(new InputStreamReader(uc.getInputStream()));
String mail = null;
//对规则进行封装
String reg = "[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
Pattern p = Pattern.compile(reg);
while ((mail = br.readLine())!=null)//读取网页里的数据{
//让正则对象和要作用的字符串相关联,获取匹配器对象
Matcher m = p.matcher(mail);
while(m.find())//判断是否匹配{
System.out.println(m.group());
}
}
}
}
----------------------
ASP.Net+Android+IOS开发、
.Net培训、期待与您交流! ----------------------详细请查看:
http://edu.youkuaiyun.com