正则表达式

正则表示的概念

  • 正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等工作。
  • 其实正则表达式是一个非常简单而且非常实用的工具。
  • 正则表达式是一个用来匹配字符串的模板。
  • 在Java中定义的任何一个字符串都可以作为正则表达式使用。
  • “表示字符串的字符串”
  • 如果正则表达式只能匹配"abc"这样的字符串,那么正则表达式就不值得学习了

    正则表达式

正则表达式有很多种匹配方法,String类下提供了直接匹配的方法:

str.matches(正则)

String regex = "abc";

String str = "abcd";

System.out.println(str.matches(regex));

正则表达式的符号

推荐一段代码,在测试下面的方法的时候,只需要修改函数中正则表达式的内容即可,运行时可多次试验。

import java.util.Scanner;

public class 练习 {
	public static void main(String[] args) {
		while(true) {
			System.out.println(method());
		}
			
	}
	private static String input() {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入你的字符:");
		String str = sc.nextLine();
		return str;
	}
	public static boolean method() {
		String str = input();
		String regex = "[abc]{4,6}";
		return str.matches(regex);
	}
	
}	

(1)预定义字符类

.

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

想要匹配这个点的时候需要加上转义“\\.”

\d

数字:[0-9]

\D

非数字: [^0-9]

\s

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

\S

非空白字符:[^\s]

\w

单词字符:[a-zA-Z_0-9]

\W

非单词字符:[^\w]

 

示例代码

System.out.println("a".matches("."));

System.out.println("1".matches("\\d"));

System.out.println("%".matches("\\D"));

System.out.println("\r".matches("\\s"));

System.out.println("^".matches("\\S"));

System.out.println("a".matches("\\w"));

(2)Greedy 数量词

X?

X,一次或一次也没有

X*

X,零次或多次,这里的多次指所有的字符个数都可以多次出现,不像之前的在true的情况下也是只有一次。比如[abc]?  aaabbbccbbb也是返回true的

X+

X,一次或多次

X{n}

X,恰好n次:这里是由前面X的元素组成只要是由n位就行,不要求哪个一定要出现n次

X{n,}

X,至少n次:同样不考虑X中元素出现几次,只要是n位往上就行

X{n,m}

X,至少n次,但是不超过m次:同样不考虑出现几次,n<=  出现次数<=m

 

示例代码

System.out.println( "a".matches(".") );

System.out.println( "a".matches("a") );

System.out.println("a".matches("a?") );

System.out.println( "aaa".matches("a*") );

System.out.println( "".matches("a+") );

System.out.println( "aaaaa".matches("a{5}") );

System.out.println( "aaaaaaaaa".matches("a{5,8}") );

System.out.println( "aaa".matches("a{5,}") );

System.out.println( "aaaaab".matches("a{5,}") );

 

(3)范围表示

[abc]

只有abc其中之一才可以     注意这里只能验证一个字符。如果输入ab或者bc等都会返回错误

[^abc]

只要不是abc其中之一就可以 

[a-zA-Z]

在a到c或者A到C的范围内都可以包括a、c,A、C。这里的范围是任意的,是按照ASCII码值进行范围的界定,而且一个中括号内可以划定多个范围

[a-d[m-p]]

这其实和上面的那个相同,都是两个范围的并集内进行划定

[a-z&&[def]]

这里后面的括号可加可不加,但是还是加上比较清晰一点,表示并集,比如1-7&&5-9,那么只有5,6,7可以返回true

[a-z&&[^bc]]

还是交集,不过后面的范围变成了一个补集

[a-z&&[^m-p]]

与上面那个类似,不过这里是把单个列举的字符变成了范围

 

示例代码

System.out.println( "a".matches("[a]") );

System.out.println( "aa".matches("[a]+") );

System.out.println( "abc".matches("[abc]{3,}") );

System.out.println( "abc".matches("[abc]+") );

System.out.println( "dshfshfu1".matches("[^abc]+") );

System.out.println( "abcdsaA".matches("[a-z]{5,}") );

System.out.println( "abcdsaA12".matches("[a-zA-Z]{5,}") );

System.out.println( "abcdsaA12".matches("[a-zA-Z0-9]{5,}") );

System.out.println( "abdxyz".matches("[a-c[x-z]]+"));

System.out.println( "bcbcbc".matches("[a-z&&[b-c]]{5,}"));

System.out.println( "tretrt".matches("[a-z&&[^b-c]]{5,}"));

4、单词边界  \b

\b 表示单词边界,除了\w中的字符外的其他字符都可以作为单词边界。

例如:"hi.*"   和  "high" 匹配

      "ahi.*" 和  "ahigh" 匹配

      "a.hi.*"和  "axhigh" 匹配

      但 "a.\\bhi.*" 和  "axhigh" 不匹配,为什么?

      因为\b表示单词的边界,空格把 a 和high分成了两个单词。也就是说 high是另一个单词的开始处在边界上,所以就匹配。而x不会把a和high分成两个单词。

思考 "a.\\bhi.*" 和  "a,high" 是否匹配?

 

示例代码

String regex = "a.\\bhi.*";   // \b不会占位 所以要配置 .   除了\w中的字符外的其他字符都可以作为单词边界

System.out.println("axhigh".matches(regex));  //false

System.out.println("a high".matches(regex));  //true

System.out.println("a#high".matches(regex));  //true

System.out.println("a$high".matches(regex));  //true

System.out.println("a_high".matches(regex));  //false

System.out.println("a9high".matches(regex));  //false

5、正则表达式的分组

    如果想匹配3个数字,正则表达式可以用如下写法: \d{3}

    但是:在实际应用中,往往需要重复多个字符,例如想重复ab两个字符,使用以下代码就不合适了[ab]{3}。 如何解决这个问题?

    使用分组:在正则表达式中,使用()来表示分组。(ab){3}。这里正确匹配就是ababab

    所谓分组就是使用小括号将一些项包括起来,使其成为独立的逻辑域,那么就可以像处理一个独立单元一样去处理小括号的内容。

   这种分组叫做捕获组,可以做反向引用

   什么是反向引用?

   反向引用指的就是使用 \组号  来表示引用前面哪一组中的内容。

 

示例代码

String regex = "(a)(b)(c)" ;// 分3组    分别为:(a)、(b)、(c) 组号为 1,2,3

System.out.println("abc".matches(regex));

 

示例代码2

 

示例代码3

6、正则的匹配功能

需求:校验QQ号,要求:必须是5~15位数字,0不能开头。没有正则表达式之前:

 public static void checkQQ(String qq){

int len = qq.length();

if(len>=5 && len <=15){

if(!qq.startsWith("0")){

try{

long l = Long.parseLong(qq);

System.out.println("qq:"+l);

}

catch (NumberFormatException e){

System.out.println("出现非法字符");

}

}

else

System.out.println("不可以0开头");

}

else

System.out.println("QQ号长度错误");

}

 

使用正则表达式:

 public static void checkQQ2(){                                     

String qq = "12345";              

String reg = "[1-9][0-9]{4,14}";  

boolean b = qq.matches(reg);      

System.out.println("b="+b);                                 

}  

7、正则的切割功能

1 根据空格对一段字符串进行切割。

public static void testSplit(){                                                                                           

String str = "1     99    4    23";                           

String[] arr = str.split(" +");                         

for(String s : arr){                                                       

System.out.println(s);                              

}                                                       

}

 

2 根据重叠词进行切割。

public static void testSplit2(){                                      

String str = "adqqfgkkkhjppppcat";

String[] arr = str.split("(.)\\1+");//这里的\\1是转义,代表的是\1,SOH文头字符。

for(String s : arr){                                  

System.out.println(s);         

}                                                                     

}

8、正则的替换功能

String类的replaceAll方法

 

示例代码

public class Demo13_替换功能 {

 

public static void main(String[] args) {

String str = "www.baidu.com";

String str2 = str.replace("w", "x");

System.out.println(str2);

 

String str3 = str.replaceAll("w","x");

System.out.println(str3);

 

String str4 = str.replaceAll(".", "x");

System.out.println(str4);

 

String str5 = str.replaceAll("[a-z]", "x");//正则表达式只能在replaceAll中使用

System.out.println(str5);

}

}

     

案例1:替换电话号码为 ******

String str = "联系我:18610637606联系我:13510637606联系我:13810637606联系我:18610637606联系我:17610637606联系我:18910637606";

public class Demo14_替换电话 {

 

public static void main(String[] args) {

 

  String str = "联系我:18610637606联系我:13510637606联系我:13810637606联系我:18610637606联系我:17610637606联系我:18910637606";

 

  String regex = "(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}";

  str = str.replaceAll(regex,"*****");

  System.out.println(str);

}

}

 2 还原口吃说话

  String str = “我我我我我我要要要要要要要要要要努努努努努努努力力力力力力”;

// 还原成 “我要努力”

public class Demo15_替换功能_还原口吃说话 {

 

public static void main(String[] args) {

 

String str = "我我我要要要要要努努努努努努努力力力力力力";   // "我要努力"

String regex = "(.)\\1+";

//str = str.replaceAll(regex, "(.)");

str = str.replaceAll(regex, "$1");  // $1在正则表达式外取某组中的内容

System.out.println(str);

}

}

9、正则的获取功能(查找子串)

查找子串同样要由 Pattern 和 Matcher 来完成

Matcher 下的常用方法

find()  是否包含匹配正则的子串

group()  取出子串

start() 符合条件子串的开始位置

end() 符合条件子串的结束位置

 

示例代码  

public class Demo16_查找子串 {

 

public static void main(String[] args) {

String str = "aaa  abcd     axss  xssdf"; // 找到所有4个长度的子串

String regex = "\\b[a-zA-Z]{4}\\b";

 

Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(str);

while(m.find()){

System.out.println(m.group());

}

}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值