正则学习

203 阅读4分钟

学习目标

(1)校验邮箱,手机号码


正则表达式定义了字符串的模式。可以用来搜索、编辑或处理文本。并不仅限于某一种语言,但是在每种语言中有细微的差别。


正则表达式基本语法

正则表达式java.util.regex 包主要包括以下三个类:

  • Pattern 类:

    pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

  • Matcher 类:

    Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

  • PatternSyntaxException:

    PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。


基本语法实战:

(1)<html>hello world</html>

预期:通过正则获取<html>标签里的内容,这里我们要获取的是hello world

String testStr = "<html>hello world</html>";
//?<=代表以<html>开头,?=</html>结束,截取其中的字符
Pattern pattern = Pattern.compile("(?<=<html>).*(?=</html>)");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    System.out.println(matcher.group());
}


(2)我们可以对(1)中的场景进行一个变化,<html></html>这对,大小写混用。

导致我们常常获取不到想要的内容?此时应该怎么办?

如:haha<Html>fengluo</HtMl>hehe

String testStr = "haha<Html>fengluo</HtMl>hehe";
Pattern pattern = Pattern.compile("(?<=<[Hh][Tt][Mm][Ll]>).*(?=</[Hh][Tt][Mm][Ll]>)");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    System.out.println(matcher.group());
}


(3)abcdefg2268232834@qq.com898afj

获取2268232834@qq.com的值

String testStr = "abcdefg2268232834@qq.com8922682328348afj";
Pattern pattern = Pattern.compile("\\d+@qq.com");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    System.out.println(matcher.group());
}


 (4)目前有lap map nap rap xap

我目前先筛选出首字母不以x开头的

也就是筛选出lap map nap rap开头的单词

正则:[^x]ap


lap map &ap cat开头的单词,我想匹配以ap结尾,不以特殊字符开始的单词

也就是匹配上lap,map

\wap

(5)正则匹配之惰性与贪婪分析

比如我有一个邮箱,“fengluo@idddd.com.cn.cnnnnn.eeeee”

我现在只想匹配@idddd.

我最初想法是:@\w+\.


没想到竟然匹配上了@idddd.com.cn.cnnnnn.

这就涉及到了贪婪匹配了。idddd.com.cn.cnnnnn这一串字符与\w+是匹配上的,这里正则默认是帮我们尽可能匹配多的。

我们可以进行可以改变,在@\w+?\.这里加上一个?号,就只会匹配上一个了,代表懒惰匹配



正则高级实战:

(1)字表达式-捕获组与非捕获组

abjjd127.0.0.1djlaj

首先先写个正则表达式来捕获127.0.0.1

String testStr = "aabbccdd127.0.0.1djajflaj";
Pattern pattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    System.out.println(matcher.group());
}

从上面看,正则写法有点复杂,我们可以进行简化

regex:(\\d{1,3}\\.){3}\\d{1,3}

加了个(),代表字表达式


<h1>abc</h1><h2>abcd</h2><h3>abcde</h3><h4>abcdef</h4>

我想要获取各个标签的内容

List<String> list = new ArrayList<>();
String testStr = "<h1>abc</h1><h2>abcd</h2><h3>abcde</h3><h4>abcdef</h4>";
Pattern pattern = Pattern.compile("(?<=<h[1-4]>).+?(?=</h[1-4]>)");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    list.add(matcher.group());
}
System.out.println(list.toString());

正则:(?<=<h[1-4]>).+?(?=</h[1-4]>)


如果标签内容前后不一致:

List<String> list = new ArrayList<>();
String testStr = "<h1>abc</h1><h2>abcd</h4><h3>abcde</h3><h4>abcdef</h4>";
Pattern pattern = Pattern.compile("(?<=<h([1-4])>).+?(?=</h\\1>)");
Matcher matcher = pattern.matcher(testStr);
while (matcher.find()) {
    list.add(matcher.group());
}
System.out.println(list.toString());

输出结果:[abc, abcde, abcdef]


学习目标实战:

(1)判断邮箱

规则:数字丶字母丶下划线+@数字丶字母(小写)+.+英文(长度为2-4)

//数字丶字母丶下划线+@数字丶字母(小写)+.+英文(长度为2-4)
String testStr = "abc1_@aff22.com";
boolean isMatch = Pattern.matches("\\w+@[0-9a-z]+\\.[a-z]{2,4}", testStr);
System.out.println(isMatch);


(2)判断手机号码

11位数字,首位为1

//11位数字,首位为1
String testStr = "28390096456";
boolean isMatch = Pattern.matches("1\\d{10}", testStr);
System.out.println(isMatch);