加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式小结

发布时间:2020-12-13 23:10:18 所属栏目:百科 来源:网络整理
导读:学习网址:http://www.w3cschool.cc/java/java-regular-expressions.html 实现目的:每四个数加个空格,数的长度不定。 例子:参考:http://biancheng.dnbcw.info/java/110082.html String num1 = "1234562222";System.out.println("1234562222".replaceAll(

学习网址:http://www.w3cschool.cc/java/java-regular-expressions.html

实现目的:每四个数加个空格,数的长度不定。

例子:参考:http://biancheng.dnbcw.info/java/110082.html

	String num1 = "1234562222";
	System.out.println("1234562222".replaceAll("d{4}(?!$)","$0 "));//这句就够了
	//String res = Pattern.compile("d{4}(?!$)").matcher(num1).replaceAll("$0 ");
	//System.out.println(res);  
	例子中$0代表匹配的表达式。结果:1234 5622 22

下面是学习期间的一些理解和总结:

(pattern)

匹配pattern并捕获该匹配的子表达式。可以使用$0…$9属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"("或者")"。

注:在正则表达式中,被小括号括起来的子表达式称为捕获组,正则表达式在求值期间将保存匹配这些捕获组表达式的输入子序列。一旦完全匹配操作完成,这些保存的代码片断可通过确定相应的组号从 Matcher对象上重新获取。捕获组可以嵌套使用,数量可以通过从左到右计算左括弧(开括号)得到。无论整个表达式是否有子组,它的捕获组总能记为组零(group zero)。

例如,正则表达式 A((B)(C(D)))可能有的捕获组编号如下所示:

组号    表达式组
0   A((B)(C(D)))
1   ((B)(C(D)))
2    (B)
3   (C(D))
4   (D)

参照下例子理解捕获组

	String num = "dog cast dogg";
	String pattern = "d(o)?(gg?)";
	Pattern r = Pattern.compile(pattern);
	Matcher m = r.matcher(num);
	int count=m.groupCount();
	System.out.println("group个数:"+count);
	if(m.find()){
		System.out.println("group 0: " + m.group(0));
		System.out.println("group 1: " + m.group(1));
		System.out.println("group 2: " + m.group(2));
	}
	
//结果如下:可看出来:()个数就是组个数 而group 0是个特殊的组,它总是代表整个表达式。该组不包括在groupCount的返回值中。
//	group个数:2
//	group 0: dog
//	group 1: o
//	group 2: g

(?=pattern)

执行正向预测先行搜索的子表达式,该表达式匹配处于匹配pattern的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

(?!pattern)

执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 可理解为 不消耗任何字符,如下例。


细节:(?=exp)也叫零宽度正预测先行断言

它断言自身出现的位置的后面能匹配表达式exp。比如bw+(?=ingb),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

(?!exp)也叫零宽度负向预测先行断言

bw*q[^u]w*b 匹配包含后面不是字母u的字母q的单词。

可是你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的w*b将会匹配下一个单词,于是bw*q[^u]w*b就能匹配整个Iraq fighting。

然而:
负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:bw*q(?!u)w*b

参考:http://www.cnblogs.com/mu-mu/archive/2013/02/06/2893581.html

注释:(零宽度正预测先行断言)仅当子表达式在此位置的右侧匹配时才继续匹配。例如,w+(?=d)与后跟数字的单词匹配,而不与该数字匹配。

最后一个小例子自己在这犯错了,所以记录一下:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
	public static void main(String[] args) {
		String s = "<BODY>" + "<H1>Welcome to my Homepage</H1>"
				+ "Content is divided into two sections:<BR>"
				+ "<H2>ColdFusion</H2>"
				+ "Information about Macromedia ColdFusion."
				+ "<H2>Wireless</H3>"
				+ "Information about Bluetooth,802.11,and more." + "</BODY>";
		
		String reg = "<[hH]([1-6])>.*</[hH]1>";

		Pattern patt = Pattern.compile(reg);
		Matcher mc = patt.matcher(s);
		
		
		System.out.println(s.replaceAll(reg,",$0+++"));
		
		while (mc.find()) {
			System.out.println(mc.group().trim());
		}
		System.out.println("------------------------------");
		
		/**
		 * 输出: <H1>Welcome to my Homepage</H1> <H2>ColdFusion</H2>
		 */
		
		String ss="ABCDEFGHIJKL";
		String reg1 = "S{4}(?!$)";

		Pattern patt1 = Pattern.compile(reg1);
		Matcher mc1 = patt1.matcher(ss);

		while (mc1.find()) {
			System.out.println("Found value: " + mc1.group(0));
			System.out.println(mc1.group().trim());
		}
		
		
		System.out.println("------------------------------");
		
		String pattern1 = "d{4}(?!$)";

		String num1 = "1234567890";
		Pattern r1 = Pattern.compile(pattern1);
		Matcher m1 = r1.matcher(num1);
		
		StringBuilder res=new StringBuilder();
		/**
		 * 写成if了,还一直纳闷怎么就匹配不出来
		 */
		while (m1.find()) {
			System.out.println("Found value: " + m1.group(0));
			res.append(m1.group(0)+",");
			System.out.println(m1.group().trim());
			
		}
		System.out.println(res);
		
		/**
		 * 输出结果如下:
		 * 	Found value: ABCD
		 *	ABCD
		 *	Found value: EFGH
		 *	EFGH
		 *	Found value: 1234
		 *	1234
		 *	Found value: 5678
		 *	5678
		 *  1234,5678,*/
		
	}
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读