正则 学习笔记子目录

字符


教程 :JavaSchool

[Q&A] 什么是普通字符?

字母、数字、下划线、汉字等文字符号。没有特殊定义的标点符号。

[Q&A] 什么是转义字符?

字符本身有特殊含义,在其前面放置 \才表示其字面意义。或其自身的字面意义前面加上 \具有了特殊含义。

\f	                                                换页符
\n	                                                换行符
\r	                                                回车符
\t	                                                制表符
\v	                                                垂直制表符

() [] {}  ^  $  *  +  ?  .  |  \	 在正则表达式里有特殊含义, \加上这些字符表示这些字符本身

\r \n \r\n 区别

拓展: java回车与换行的区别、CR LF CRLF区别、 \r \n \r\n区别、如何获取换行符呢?如何以换行符来分隔字符串?

[Q&A] java中对[的正则匹配为什么需要用两个\转义?

第一个\ 是对后面 \ 的转义,\\[ 表示[字符本身。 [Ref] java中对[的正则匹配为什么需要用两个\转义?

Pattern类

Java中Matcher类的matches和find的区别

Java中Matcher类的matches和find的区别

字符集

[Q&A] 什么是标准字符集?

符号含义举例
\d与任何十进制数字匹配\d 等效于 [0-9]
\D与任何不是十进制数的字符匹配\D 等效于 [^0-9]
\w与任何单词字符匹配\w 等效于 [a-zA-Z_0-9]
\W与任何非单词字符匹配\W 等效于 [^a-zA-Z_0-9]
\s与任何空白字符匹配\s 等效于 [ \f\n\r\t\v],注意还包含空格
\S与任何非空白字符匹配\S 等效于 [^ \f\n\r\t\v]
[\s\S]所有字符
.通配符,匹配\n 外任一单个字符

[Q&A] 正则表达式 \w 可以匹配汉字吗

可以!\w 表示 A~Za~z0~9_ 中任意一个。但是在某些情况下,\w也会匹配本地字符集,比如中文系统的中文,全角数字等。一是要看你的系统是什么系统,中文系统下是可以匹配汉字的。二是要看你的应用环境,如果是在C# 程序中,是可以匹配汉字的,在javascript或验证控件中,是不可以匹配汉字的。所以在明确要求是A~Z,a~z,0~9,_ 中的一个的时候,用[A-Za-z0-9_],而不用\w [Ref] 正则表达式 \w 可以匹配汉字吗

split(“ “) 和 split(“\s+“) 的区别

Further Reading :split(“ “) 和 split(“\s+“) 的区别

[Q&A]什么是自定义字符集?

1・用[]存放自定义的字符。
2・[] 可存放 . 外的标准字符集, . 仅表示 . 本身。
3・除 ^- 其他特殊符号在 [] 中都失去特殊含义。 ^ 表示取反, - 表示范围。

小练习

[a5@]                匹配 "a""5""@" 之一的字符             验证第1[\d.+]               匹配: 数字 或 .+                         验证第2[^abc]               匹配 "a","b","c" 之外的任意一个字符           验证第3[c-k]                匹配 "c"~"k" 之间的任意一个字母               验证第3条

Pattern.compile("[a5@]").matcher("a").matches();  // true
Pattern.compile("[a5@]").matcher("aa").matches(); // false aa为非单字符所以match不上
Pattern.compile("[a5@]").matcher("aa").find();	   // true

Pattern.compile("[\\\\]").matcher("\\").matches() // true

[Q&A] 正则表达式[\w]+,\w+,[\w+] 三者有何区别?

[\w]+ \w+ 没有区别,都是匹配数字、字母、下划线的多个字符
[\w+] 表示匹配数字、字母、下划线和加号本身字符

[Q&A] [ABC]+,[\w.-+]+ 表达什么?

[ABC]+ 匹配"AAABBBCCC,BACCBACAACBAC,...",不一定按固定A…B…C…次序排列。
[\w.\-+]+ 匹配[0-9a-zA-Z_].-+ 字符, 在[]+表示即至少1次或多次。

Pattern.compile("[\\w.\\-+]+").matcher("s").matches() // true
Pattern.compile("[\\w.\\-+]+").matcher(".").matches() // true
Pattern.compile("[\\w.\\-+]+").matcher("-").matches() // true
Pattern.compile("[\\w.\\-+]+").matcher("+").matches() // true

[Ref] 正则表达式[\w]+,\w+,[\w+] 三者区别? [],[ABC]+,[\w./-]+ 表达什么

贪婪匹配

[Q&A] 什么是贪婪限定符、惰性限定符?

贪婪限定符惰性限定符描述
**?匹配 >=0 次,相当于 {0,}
++?匹配 >=1 次,相当于 {1,}
???匹配 0 or 1 次,相当于 {0,1}
{n}{n}?匹配 =n 次
{n,}{n,}?匹配 >=n 次
{n,m},{n,m}?匹配 n<= <=m 次
a*     "aabab" 匹配 "aa""""a"""""
a*?    "aabab" 匹配 """"""""""""
# 感觉 a*? 的效果就是 a{0}, 没啥实际意义吧

a+     "aabab" 匹配 "aa""a"
a+?    "aabab" 匹配 "a""a""a"
# 感觉 a+? 的效果就是 a{1}, 没啥实际意义吧

a?     "aabab" 匹配 "a""a""""a"""""
a??    "aabab" 匹配 """"""""""""
# 感觉 a?? 的效果就是 a{0}, 没啥实际意义吧

Matcher matcher = Pattern.compile("a*").matcher("aabab");
while (matcher.find()) {
    System.out.print(",\"" + matcher.group()+"\"");
}
[a-zA-Z]{2}  "abcde"    匹配到 "ab""cd"

a{3}         "aaabaaaa" 匹配到 "aaa""aaa"
a{3}"aaabaaaa" 匹配到 "aaa""aaa"
# 总结:感觉 a{3} 和 a{3}? 没区别

a{3,}        "aabaaabaaaa"匹配到"aaa""aaaa"
a{3,}"aabaaabaaaa"匹配到"aaa""aaa"
# 总结:感觉a{3,}?的效果就是 a{3}

a{1,3}       "aabaaabaaca" 匹配 "aa""aaa""aa""a"  
a{2,3}?      "aabaaabaaca" 匹配 "aa""aa""aa"
# 总结:感觉a{2,3}?的效果就是 a{2}

[Q&A] 什么是贪婪匹配, 非贪婪匹配

.* 贪婪模式:使整个匹配成功的前提下使用最多的重复
.*? 非贪婪模式:使整个匹配成功的前提下使用最少的重复 [Ref] 正则表达式(.*?)惰性匹配()

# aabbabb里查找以a开始以b结束的字符串 

# a.*b
Matcher matcher = Pattern.compile("a.*b").matcher("aabbab");
while (matcher.find()) {
    System.out.println(matcher.group());
}
# aabbab


# a.*?b
Matcher matcher = Pattern.compile("a.*?b").matcher("aabbab");
while (matcher.find()) {
    System.out.println(matcher.group());
}
# aab
# ab

字符边界

[Q&A] 什么是字符边界

[Ref] 正则字符边界

匹配模式

[Q&A] 什么是匹配模式

1、IGNORECASE 匹配时忽略大小写。默认情况下,区分大小写。
2、SINGLELINE 单行模式,整个文本看作一个字符串,只有一个开头,一个结尾。
3、MULTILINE 多行模式,每行都是一个字符串,都有开头和结尾。如果需要仅匹配字符串开始和结束位置,可以使用 \A\Z

正则匹配忽略大小写

Pattern.compile("^(?i)doc$").matcher("doc").matches() // true
Pattern.compile("^(?i)doc$").matcher("DOC").matches() // true

[Q&A] 选择符

| 表 “或” 关系,匹配左边或者右边

th(e|is|at)            匹配 "the" "this" "that"

捕获组

[Q&A] 捕获组(exp)

1・在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
2・获取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到,每一对括号会分配一个编号,从 1 开始自动编号。编号为 0 的是由整个正则表达式匹配的文本 。
参考: Java正则表达式(简介+捕获组+语法+Matcher 类的方法+…干货!!.)
参考: Java正则表达式–Matcher.group函数的用法
参考: matcher.group()方法的使用

String line = "This order was placed for QT123! OK?";
Matcher matcher = Pattern.compile("(\\D*)(\\d+)(.*)").matcher(line);
if (matcher.find()) {
    System.out.println("Found value: " + matcher.group(0));   // This order was placed for QT123! OK?
    System.out.println("Found value: " + matcher.group(1));   // This order was placed for QT
    System.out.println("Found value: " + matcher.group(2));   // 123
    System.out.println("Found value: " + matcher.group(3));   // ! OK?
} else {
    System.out.println("NO MATCH");
}

[Q&A] 非捕获组(?:exp)

一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配的内容,这时可以用非捕获组来抵消使用()带来的副作用 。

String line = "This order was placed for QT123! OK?";
Matcher matcher = Pattern.compile("(?:\\D*)(?:\\d+)(?:.*)").matcher(line);
if (matcher.find()) {
    System.out.println("Found value: " + matcher.group());   // This order was placed for QT123! OK?
} else {
    System.out.println("NO MATCH");
}

反向引用

[Q&A] 反向引用

每一对()会分配一个编号,从 1 开始自动编号。通过反向引用,可以对分组已捕获的字符串进行引用。
[Ref] Java正则表达式之反向引用(Backreferences)

String source = "1234567890, 12345,  and  9876543210";
Matcher matcher = Pattern.compile("\\b(\\d{3})(\\d{3})(\\d{4})\\b").matcher(source);
while (matcher.find()) {
    System.out.println("Phone: " + matcher.group() + ", Formatted Phone:  (" + matcher.group(1) + ") " + matcher.group(2) + "-" + matcher.group(3));
}

Phone: 1234567890, Formatted Phone:  (123) 456-7890
Phone: 9876543210, Formatted Phone:  (987) 654-3210
String source = "1234567890, 12345, and 9876543210";
Matcher matcher  = Pattern.compile("\\b(\\d{3})(\\d{3})(\\d{4})\\b").matcher(source);
String formattedSource = matcher.replaceAll("($1) $2-$3");

(123) 456-7890, 12345, and (987) 654-3210

预搜索

[Q&A] 预搜索(零宽断言)

[Ref] : 关于正则表达式中?=、?!、?<=、?<!、?:的理解与应用
[Ref] : 正则表达式中?=和?:和?!的理解

# 后面是苹果的我喜欢
Pattern.compile("我喜欢(?=苹果)").matcher("我喜欢苹果汁").find());    		 	true
Pattern.compile("我喜欢(?=苹果)").matcher("我喜欢柠檬汁").find());    			false
Pattern.compile("我喜欢(?=苹果)").matcher("我喜欢苹果汁").replaceAll("我讨厌"));  我讨厌苹果汁
Pattern.compile("我喜欢(?=苹果)").matcher("我喜欢柠檬汁").replaceAll("我讨厌"));	我喜欢柠檬汁

# 后面不是苹果的我喜欢
Pattern.compile("我喜欢(?!苹果)").matcher("我喜欢苹果汁").find());				false
Pattern.compile("我喜欢(?!苹果)").matcher("我喜欢柠檬汁").find());				true
Pattern.compile("我喜欢(?!苹果)").matcher("我喜欢苹果汁").replaceAll("我讨厌"));	我喜欢苹果汁
Pattern.compile("我喜欢(?!苹果)").matcher("我喜欢柠檬汁").replaceAll("我讨厌"));	我讨厌柠檬汁

# 前面是苹果的汁
Pattern.compile("(?<=苹果)汁").matcher("我喜欢苹果汁").find());					true
Pattern.compile("(?<=苹果)汁").matcher("我喜欢柠檬汁").find());					false
Pattern.compile("(?<=苹果)汁").matcher("我喜欢苹果汁").replaceAll("干"));			我喜欢苹果干
Pattern.compile("(?<=苹果)汁").matcher("我喜欢柠檬汁").replaceAll("干"));			我喜欢柠檬汁

# 前面不是苹果的汁
Pattern.compile("(?<!苹果)汁").matcher("我喜欢苹果汁").find());					false
Pattern.compile("(?<!苹果)汁").matcher("我喜欢柠檬汁").find());					true
Pattern.compile("(?<!苹果)汁").matcher("我喜欢苹果汁").replaceAll("干"));			我喜欢苹果汁
Pattern.compile("(?<!苹果)汁").matcher("我喜欢柠檬汁").replaceAll("干"));			我喜欢柠檬干

算法中遇到的正则表达式

[代码总结] 算法中遇到的正则表达式

待消化

匹配POSIX字符类
正则表达式入门(四)选择,分组和向后引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值