java正则表达式

     简介:

 正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表通常被用来检索\替换\分割\匹配那些符合某个模式(规则)的文本。

1、概念:
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
 正则表达式的特点是:
1. 灵活性、逻辑性和功能性非常的强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。

3.如果大规模数据的校验最好不要使用正则,效率非常差。CPU的处理能力会全部耗费在处理这几个正则上。
由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。

 正则表达式对字符串的常见操作:
   1、匹配 其实使用的就是String类中的matches()方法
   2、切割 其实使用的就是String类中的split()方法
   3、替换  其实使用的就是String类中的replaceAll()方法
   4、获取 

2-正则表达式(常见的规则)

字符类 
[abc] ----   a、b 或 c(简单类)(某一位上只能是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](减去) 

预定义字符类 
.   ----  任何字符(与行结束符可能匹配也可能不匹配) 
\d  ----  数字:[0-9] 
\D  ----  非数字: [^0-9] 
\s  ----  空白字符:[ \t\n\x0B\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 次 

[注]:上面的规则中,发现"^"既可以作为取非的意思又可以作为行的开头,怎么回事呢?

这是由于则表达式中字符在[ ]里面和不在[ ]中意义会发生一些变化,比如:

\b指单词边界,但是在[ ]中就是指退格符,表示一个符号

^一般指起始位置,而在[ ]的开头指 ''非''的意思,即排除

在[ ]中,字符"-"有不同含义,表示普通字符,或者标志一个区间(在两个有序字符中间).

方法演示:

1 匹配


/*
 * matches()方法
 */
public static void testMatch(){
 //匹配手机号码
 String tel = "13148098167";
 String regex = "1[358][0-9]{9}";
 //String regex = "1[358]\\d{9}";
		
 boolean b = tel.matches(regex);
 System.out.println(tel+" : "+b);
}

 2 分割:

    /*
	 * 
	 * split()方法
	 * 
	 */
	public static void method2(){
		
		//String str = "123tttt456mmmmmm789";//组

		//String [] names = str.split("(.)\\1+");
// (.)\\1+意思是:以连续重复的字符为一组分割点,其中()表示分组的意思
		
		for (String name : names) {
			System.out.println(name);
		}
	}

()表示分组:
例如:((A)(B(C))) 就表示大分组中包含这样几个小的分组

(A)  -- (B(C))  -- (C)--(B(C))//B不是一个分组,B和(C)才是一个完整分组

3 替换

String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";

str = str.replaceAll("(.)\\1+", "#"); // 使用 # 替换
// 1代表第一组  1是普通数字  所以加 \\1
// 直接用数字编号 代表组 1 就代表第一组
str = str.replaceAll("(.)\\1+", "$1");
// 使用单个自身替换多个连续的自身,这个$1表示第一个分组,那么为什么使用$1就可以替换全部重复字符呢?
//而不需要$2$3$4......?这是因为无法确定有多少分组
//所以无法使用$2$3代替第二个分组,第三个分组.就使用循环方式实现

String tel = "15856567788";// 158****7788
tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
//这里组的数量是确定的,所以可以使用$2表示第二组

Pattern 类:
* 指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,
* 依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。 
    
(1)将正则规则进行对象的封装
     Pattern p = Pattern.compile("a*b");
(2)通过正则对象的matcher方法将字符串相关联。获取要对字符串操作的匹配器对象Matcher。
     Matcher m = p.matcher("aaaaab");
(3)通过Matcher匹配器对象的方法对字符串进行操作。
     boolean b = m.matches();

4 获取:

// 获取三个字母组成的单词
import java.util.regex.Matcher;
import java.util.regex.Pattern;

String str = "this is a sad story but i feel happy";
String regex = "[a-z]{3}";
String regex = "\\b[a-z]{3}\\b";//单词边界:\\b

//1、将正则规则进行对象的封装
 Pattern p = Pattern.compile(regex);
//2、通过正则对象获取匹配器对象
 Matcher m = p.matcher(str);
//3、使用Matcher对象的方法对字符串进行操作。

// 查找find();
//  m.find();//只查找一次
//  System.err.println(m.group());//获取匹配的子序列

 while(m.find()){
     System.out.println(m.group());//获取匹配的子序列  		
     System.out.println(m.start()+" : "+m.end());//
 }
//
 Pattern p = Pattern.compile("\\d{3,5}");
  String s = "123-34345-234-00";
  Matcher m = p.matcher(s);//注意,matcher是全局匹配.这里明显是不匹配.但是,由于s里面的"123"和p是匹配的,所以他会将这三个数字去掉.下次调用匹配方法的时候,是将剩余的字符串来继续匹配
  p(m.matches());
  m.reset();//重新设置到最开始..如果这里没有这一步,下面的匹配将受到影响...
  p(m.find());//find方法是部分匹配..也就是说,只要找到有匹配的字符段就算匹配...但是,他和matcher方法一样也会将s里面已经匹配的字符去掉....这里匹配的是"123" 
  p(m.find());//剩余的字符"-34345-234-00"继续匹配.匹配的是"34345"
  p(m.find());//剩余字符"-234-00"继续匹配.匹配的是"234"
  p(m.find());//剩余字"-00"符继续匹配.已经没有匹配的字符,所以这个方法不匹配.
  p(m.lookingAt());//lookingAt方法也是部分匹配,但是他都是从最开始进行匹配...所以每次都是匹配"123"会有陷入死循环的危险
注意:如果是需要获取符合正则条件的数据,一般是用 Pattern

方法:  
matches - 永远匹配整个字符串
find - 找匹配的子字串 如果 matches 和 find  一起使用  会影响 find的结果,可以使用reset恢复结果
lookingAt - 每次都是从头开始找,可能陷入死循环,具体见代码

start_end

p(m.start() + "-" + m.end());//输出匹配的子字符串的起始位置和结束位置 0-3

[注]:如果没有匹配  会报错

String_Replacement
//replacement
Pattern.CASE_INSENSITIVE 忽略大小写

用法:Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
replaceAll()
appendReplacement()
appendTail()
分组
//group  

Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}");//3-5位的数字,2位的字母
Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})");//3-5位的数字,2位的字母   小括号代表分组
String s = "123aa-34345bb-234cc-00";
Matcher m = p.matcher(s);
p(m.group());//打印 所有
p(m.group(1));// 打印 数字  为什么是1  因为 数字是第一组
p(m.group(2));// 打印 字母  为什么是2  因为 数字是第二组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值