黑马程序员____基础____正则表达式

------- android培训、java培训、期待与您交流! ----------

一,,正则表达式(特点)。

     1,正则表达式:符合一定规则的表达式

     2,作用:专门用于操作字符串。对字符串即简单又便捷的操作就是正则表达式。

        好处:可以简化对字符串的复杂操作。

        特点:用一些特定的符号来表示一些代码操作,这样就可以简化书写。所以学习正则表达式就是在学习一些特殊符号的使用。

        弊端:符号定义越多,正则越长,阅读性越差。

     3public boolean matches(String regex)告知此字符串是否匹配给定的正则表达式。 调用此方法的 str.matches(regex) 形式与以下表达式产生的结果完全相同: Pattern.matches(regex, str)参数:regex - 用来匹配此字符串的正则表达式 返回:当且仅当此字符串匹配给定的正则表达式时,返回 true

     4,示例代码:

class RegexDemo {
	public static void main(String args[]) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String line = null;
		boolean b = false;
		while (null != (line = br.readLine())) {// 注意,到流的未尾才返回:null。
			if (checkQQ_2(line)) {
				break;
			}
		}
		br.close();
	}

	// 对QQ号进行校验:只能是5-15位的,0不能开头,只能是数字。
	public static boolean checkQQ_2(String qq) {
		// 1,1-9之间的数 2,0-9之间 3,第二个数出现4-14次。
		String regex = "[1-9][0-9]{4,14}";// 注意书写的格式。正则表达式。
		boolean flag = false;
		if (flag = qq.matches(regex)) {
			System.out.println("qq:" + qq);
		} else {
			System.out.println("你输入的不合法,请重新输入!");
		}
		return flag;
	}

	public static boolean checkQQ_1(String qq) {// 这种方式是用String类中的方法进行组合,代码过于冗长。。。。。。。
		boolean b = false;
		int len = qq.length();
		if (len >= 5 && len <= 15) {
			if (!qq.startsWith("0")) {
				try {
					long l = Long.parseLong(qq);
					System.out.println("qq:" + l);
					b = true;
				} catch (NumberFormatException e) {
					System.out.println("你输入的QQ号中有非数字!");
				}

				/*
				 * char ch[]=qq.toCharArray(); boolean flag=true; for(int
				 * i=0;i='0'&&ch[i]<='9')) {
				 * flag=false; break; } } if(flag) {
				 * System.out.println("你的QQ号是:"+qq); b=true; } else {
				 * System.out.println("你输入的QQ号中有非数字!"); }
				 */
			} else {
				System.out.println("QQ号不能以0开头!");
			}
		} else {
			System.out.println("您输入的QQ号位数不对!");
		}
		return b;
	}
}





二,正则表达式(匹配)。

    1,正则表达式的构造摘要:

       11,字符类 

[abc] a或 c(简单类) (这里的元素不仅仅是三个,可以是多个)元素之间可以重复。

[^abc] 任何字符,除了 a或 c(否定) 

[a-zA-Z] a 到 或 到 Z,两头的字母包括在内(范围) 

[a-d[m-p]] a 到 或 到 p[a-dm-p](并集) 

[a-z&&[def]] d或 f(交集) 

[a-z&&[^bc]] a 到 z,除了 和 c[ad-z](减去) 

[a-z&&[^m-p]] a 到 z,而非 到 p[a-lq-z](减去 )

  [1-456789]表示的是14(包括4),和56789之中的任何一个数都符合规定。

  [^1-456789]表示的是14(包括4),和56789之外的任何一个字符都符合规定,之内的都不符合规定。

        12,预定义字符类 

任何字符(与行结束符可能匹配也可能不匹配) 

\d 数字:[0-9] 

\D 非数字: [^0-9] 

\s 空白字符:[ \t\n\x0B\f\r] 

\S 非空白字符:[^\s] 

\w 单词字符:[a-zA-Z_0-9]  注意:抱括下划线在内_(因为java的标识符包括_在内,而$虽然也是java的单词字符,但因为$具有特殊的意义,所以不定义在这里,而在这里的所谓的单词是指:符合java标识符所规定的变量名、包名或关键字等等)

\W 非单词字符:[^\w] 

       13Greedy 数量词(X可以是字符也可以是数字) 

X?      X,一次或一次也没有  最多只能是一次,最少当然是0次。

X*      X,零次或多次 

X+      X,一次或多次 

X{n}    X,恰好 次 

X{n,}    X,至少 次 

X{n,m}  X,至少 次,但是不超过 次 (包括m次)

       14,字符 

字符 

\\ 反斜线字符 

\0n 带有八进制值 的字符 n (0 <= n <= 7) 

\0nn 带有八进制值 的字符 nn (0 <= n <= 7) 

\0mnn 带有八进制值 的字符 mnn0 <= m <= 30 <= n <= 7) m为什么要小于等于3?

\xhh 带有十六进制值 0x 的字符 hh 

\uhhhh 带有十六进制值 0x 的字符 hhhh 

\t 制表符 ('\u0009') 

\n 新行(换行)符 ('\u000A') 

\r 回车符 ('\u000D') 

\f 换页符 ('\u000C') 

\a 报警 (bell) 符 ('\u0007') 

\e 转义符 ('\u001B') 

\cx 对应于 的控制符 

    2,具体操作功能:

       11,匹配:String   matches方法。(正则表达式是用一些符号来表示一些复杂的代码)用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false

       12String类里的方法:public boolean matches(String regex)告知此字符串是否匹配给定的正则表达式。 调用此方法的 str.matches(regex) 形式与以下表达式产生的结果完全相同: Pattern.matches(regex, str)参数:regex - 用来匹配此字符串的正则表达式 返回:当且仅当此字符串匹配给定的正则表达式时,返回 true 抛出: PatternSyntaxException - 如果正则表达式的语法无效。从以下版本开始: 1.4 。另请参见:Pattern

      13Pattern类里的方法:public static boolean matches(String regex,  CharSequence input)编译给定正则表达式并尝试将给定输入与其匹配。 调用此便捷方法的形式 :Pattern.matches(regex, input);与表达式 Pattern.compile(regex).matcher(input).matches() 的行为完全相同。 如果要多次使用一种模式,编译一次后重用此模式比每次都调用此方法效率更高。参数:regex - 要编译的表达式input - 要匹配的字符序列 抛出: PatternSyntaxException - 如果表达式的语法无效。

   3,示例代码:

import java.io.*;

class RegexDemo {
	public static void main(String args[]) throws IOException {
		// demo();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		System.out.println("请输入你的手机号码,注意,最多只能输入5次:");
		for (int i = 0; i < 5; i++) {
			boolean b = true;
			line = br.readLine();
			if (b = checkTel(line)) {
				break;
			}

			if (!b && i == 4) {
				System.out.println("对不起,你输入的次数已到,感谢使用!Bye bye....");
			}
		}
	}

	public static void demo() {
		String s1 = "b8";
		// 字符类:[bcd]这个规则:它所规定的字符串的第一个字符只能是:b或c或d 中的任意一个
		// 当该字符串有且只有一个字符时才返回:true,否则返回false。
		// String regex="[bcd][a-z]";//该字符串中的第二个字符范围:a-z。
		// String regex="[a-zA-Z]\\d";//1,a-Z字符 2,[0-9],注意转意字符的写法:\\d。
		String regex = "[a-zA-Z]\\d?";// ?表示它前面的字符可以不出现,或出现一次。
		boolean b = s1.matches(regex);
		System.out.println(b);
	}

	public static boolean checkTel(String tel) {// 13xxx 15xx 18xxx 11位。
		boolean flag = false;
		String regex = "1[358]\\d[9]";// 确定的就直接写。
		if (flag = tel.matches(regex)) {
			System.out.println("你的手机号码:" + tel);
		} else {
			System.out.println("你输入的手机号码不正确!请重新输入:");
		}
		return flag;
	}
}





三,正则表达式(切割)。

    1public String[] split(String regex)根据给定正则表达式的匹配拆分此字符串。 该方法的作用就像是使用给定的表达式和限制参数 来调用两参数 split 方法。因此,所得数组中不包括结尾空字符串。 例如,字符串 "boo:and:foo" 使用这些表达式可生成以下结果: Regex 结果 

: { "boo", "and", "foo" } 

o { "b", "", ":and:f" } //所得的字符数组中不包括结尾的空字符串。但是中间是包括的,比如这里的{"b", "", ":and:f"}

参数:regex - 定界正则表达式 返回:字符串数组,它是根据给定正则表达式的匹配拆分此字符串确定的 。抛出: PatternSyntaxException - 如果正则表达式的语法无效。从以下版本开始: 1.4 另请参见:Pattern。还有一个split(String str,int  limit)自己可以看看。

   2当想要对一个规则重用的时候可以将其封装为组,组用“( )”来封装

   3split方法和matches方法不一样,split方法不满足还会继续往下读,而matches方法如果发现不满足的元素则就不会往下读,直接返回false

   4,为了可以让规则的结果被重用,可以将规则封装成一个组,用( )来完成。组的出现都是有编号的,0是被正则的“字符串”的编号,从1开始,想要使用已有的组可以通过 : \nn就是组的编号)的形式来获取(捕获)。 看有多少组看有多少个左括号。比如:(((())()))5组。组的编号还是依左括号来定,从1开始,括号是从“外往里的匹配的”。

   5,以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。 

   6,组和捕获 :

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组: 

1     ((A)(B(C))) 

2     (A) 

3     (B(C)) 

4     (C) 

组零始终代表整个表达式。 之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。 与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串 "aba" 与表达式 (a(b)?)+ 相匹配,会将第二组设置为 "b"。在每个匹配的开头,所有捕获的输入都会被丢弃。 以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。

   7,如果如:(([a-f])(c))后面没有“\\n”则按照正常顺序处理。

   8,比如:"(([a-f](c)))\\2"  "([a-f](c))\\1"([a-c])\\1"  等,因为后面的\n(n表示的是组号)捕获的是前面第n个组中的内容。像这样的,前面的内容和后面内容得一样才可以,比如:acac  dcdc  不可以:acbc  dcfc等。 

   

   9,一些概念:

                                                 反斜线、转义和引用 

反斜线字符 ('\') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \\ 与单个反斜线匹配,而 \{ 与左括号匹配。 在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分,而数字(09)字符串前面则可以用“\”。 根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\\(hello\\)"。 

字符类 

字符类可以出现在其他字符类中,并且可以包含并集运算符(隐式)和交集运算符 (&&)。并集运算符表示至少包含其某个操作数类中所有字符的类。交集运算符表示包含同时位于其两个操作数类中所有字符的类。 字符类运算符的优先级如下所示,按从最高到最低的顺序排列: 

1     字面值转义     \x 

2     分组 [...] 

3     范围 a-z 

4     并集 [a-e][i-u] 

5     交集 [a-z&&[aeiou]] 

注意,元字符的不同集合实际上位于字符类的内部,而非字符类的外部。例如,正则表达式 在字符类内部就失去了其特殊意义,而表达式 变成了形成元字符的范围。 

行结束符

行结束符 是一个或两个字符的序列,标记输入字符序列的行结尾。以下代码被识别为行结束符: 

新行(换行)符 ('\n')、 

后面紧跟新行符的回车符 ("\r\n")、 

单独的回车符 ('\r')、 

下一行字符 ('\u0085')、 

行分隔符 ('\u2028') 或 

段落分隔符 ('\u2029)。 

如果激活 UNIX_LINES 模式,则新行符是唯一识别的行结束符。 

如果未指定 DOTALL 标志,则正则表达式 可以与任何字符(行结束符除外)匹配。 默认情况下,正则表达式 和 忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活 MULTILINE 模式,则 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于 MULTILINE 模式中时,仅在行结束符之前或输入序列的结尾处匹配。 





四,正则表达式(替换)。

    1public String replaceAll(String regex,  String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。调用此方法的 str.replaceAll(regex, repl) 形式与以下表达式产生的结果完全相同:Pattern.compile(regex).matcher(str).replaceAll(repl)注意,在替代字符串中使用反斜杠 (\) 和美元符号 ($) 与将其视为字面值替代字符串所得的结果可能不同;请参阅 Matcher.replaceAll。如有需要,可使用 Matcher.quoteReplacement(java.lang.String) 取消这些字符的特殊含义。 参数:regex - 用来匹配此字符串的正则表达式replacement - 用来替换每个匹配项的字符串 返回:所得 String。抛出: PatternSyntaxException - 如果正则表达式的语法无效。从以下版本开始: 1.4 另请参见:Pattern

   2,示例代码:

class RegexDemo2{
	public static void main(String args[]){
    		//String str="welj456464dfsadf46464fd564adfd564654dfa";//数字大于等于5个的替换成#.
    		//replaceAllDemo("\\d{5,}",str,"#");
    
    		//String str="sdlfjjsdfoedddddlfeo0rzzdkf";//将叠词替换成#号。
    		//replaceAllDemo("(.)\\1+",str,"#");
    
    		String str="sdlfjjsdfoedddddlfeo0rzzdkf";//将叠词替换成单个字母。
    		replaceAllDemo("(.)\\1+",str,"$1");//$1表示拿regex组合中的第一个组。
   }
   public static void replaceAllDemo(String regex,String str,String newStr){
		str=str.replaceAll(regex,newStr);
		System.out.println("替换后的字符串:"+str);
	}
}



五,正则表达式(获取)。

    1,将字符串中符合规则的子串取出。

    2,操作步骤:

     21,将正则表达式封装成对象。

     22,让正则对象和要操作的字符串相关联。

     23,关联后,获取正则匹配引擎。

     24,通过引擎对符合规则的子串进行操作,比如取出。

   4public static Pattern compile(String regex)将给定的正则表达式编译到模式中。参数:regex - 要编译的表达式 。

   6public Matcher matcher(CharSequence input)创建匹配给定输入与此模式的匹配器。 参数:input - 要匹配的字符序列 返回:此模式的新匹配器。

   7String 类里的macthes方法其实是由PatternMacther这两个对象来完成的。只不过被String类的方法封装后,用起来比较简单。但是功能却单一。

   8public String group()返回由以前匹配操作所匹配的输入子序列。 对于具有输入序列 的匹配器 m,表达式 m.group() 和 s.substring(m.start(), m.end()) 是等效的。 注意,某些模式(例如,a*)匹配空字符串。当模式成功匹配输入中的空字符串时,此方法将返回空字符串。 指定者:接口 MatchResult 中的 group返回:以前匹配操作所匹配的字符串形式的子序列(可能为空)。

   9public boolean find()尝试查找与该模式匹配的输入序列的下一个子序列。 此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。 如果匹配成功,则可以通过 startend 和 group 方法获取更多信息。 返回:当且仅当输入序列的子序列匹配此匹配器的模式时才返回 true

   10,边界匹配器 

^    行的开头 

$    行的结尾 

\b   单词边界 

\B   非单词边界 

\A   输入的开头 

\G   上一个匹配的结尾 

\Z   输入的结尾,仅用于最后的结束符(如果有的话) 

\z   输入的结尾 

    7public int start()返回以前匹配的初始索引。 指定者:接口 MatchResult 中的 start返回:第一个匹配字符的索引。索引是从0开始的。

    8public int end()返回最后匹配字符之后的偏移量。 指定者:接口 MatchResult 中的 end返回:最后匹配字符之后的偏移量。索引是从0开始的。

    9start()方法和end()方法是包含头不包含尾。

    10,如果matches方法和find方法是同一个匹配器的,则它们操作的共同字符串的角标是前后一致的。同一个匹配器用的是同一个指针。


------- android培训、java培训、期待与您交流! ----------

详情请查看:http://edu.csdn.net/heima

你可能感兴趣的:(java学习笔记)