定义:一些用来匹配和处理文本的字符串
主要用途:搜索,替换
1. 匹配单个字符
.字符(英文符号)可以匹配任何一个单一的字符、字母、数字、甚至是.本身。但是在绝大多数的正则表达式实现里,不能匹配换行符
\.意思是匹配.本身,而不是任意字符
2. 匹配一组字符
这个主要通过字符集的方式来实现。用[]来定义一个字符集. [a-z], [A-Z], [0-9]
取非匹配:^, [^0-9], ^的效果作用于给定字符集合中的所有字符或字符区间,而不仅限于在^字符后面的那一个字符或字符区间
3. 元字符
元字符要匹配本身的话,需要用\来进行转义
空白元字符:
[\b] 回退(并删除)一个字符(backspace键)
\f 换页符
\n 换行符
\r 回车符
\t 制表符(Tab键)
\v 垂直制表符
\s 任何一个空白字符,等价于[\f\n\r\t\v]
\S 任何一个非空白字符,等价于[^\f\n\r\t\v] 注意:[\b]不包含在内
数字元字符:
\d 任何一个数字字符,等价于[0-9]
\D 任何一个非数字字符,等价于[^0-9]
字母数字元字符:
\w 任何一个字母数字字符(大小写均可)或下划线字符,等价于[a-zA-Z0-9_]
\W 任何一个非字母数字或下划线字符,等价于[^a-zA-Z0-9_]
16进制:\x0a == \n,ascii字符10
8进制: \012 等价于上面
POSIX字符类
[:alnum:] 任何一个字母或数字,等价于[a-zA-Z0-9]
[:alpha:] 任何一个字母,等价于[a-zA-Z]
[:blank:] 空格或制表符,等价于[\t ]
[:cntrl:] ASCII控制字符(ASCII0-31,再加上ASCII127)
[:digit:] 任何一个数字,等价于[0-9]
[:graph:] 跟[:print:]一样,但不包括空格
[:lower:] 任何一个小写字母,等价于[a-z]
[:print:] 任何一个可打印字符
[:punct:] 既不属于[:alnum:],也不属于[:cntrl:]的任何一个字符
[:space:] 任何一个空白字符,包括空格,等价于[\f\n\r\t\v ]
[:upper:] 任何一个大写字母,等价于[A-Z]
[:xdigit:] 任何一个16进制数字,等价于[a-fA-F0-9]
4. 匹配一个或多个连续字符
+ a+,意思是匹配1个或多个字符a;[0-9]+,意思是匹配一个或多个数字
* 用法跟+相同,但是匹配0个或多个连续字符
? 匹配0个或1个字符(或字符集合)
a{9} 匹配连续9个a
[0-9]{9} 匹配连续9个数字字符
{2} 重复2次
{2,4} 重复2-4次
{2,} 重复至少2次,无上限
贪婪型元字符 * + ? {n, } 匹配优先
非贪婪型元字符 *? +? ?? {n, }? 忽略优先
5. 位置匹配
\b 匹配一个单词的开头或末尾
\B 不匹配一个单词边界 (这个vim也不支持,不演示了,不过notepad++支持,我试过)
\< 匹配一个单词的开头 不是所有的编辑器都支持
\> 匹配一个单词的结束
单词边界 \b \B \< \>
字符串边界 ^ $ 分行匹配模式 (?m)
6. 子表达式
子表达式,用()来定义
常见用途: 对重复次数元字符的作用对象做出精确的设定和控制; 对|操作符的OR条件做出准确的定义; 如有必要,子表达式还允许嵌套使用
子表达式可以嵌套
7. 回溯引用
用来进行大小写转换的元字符
\E 结束\L和\U转换
\L 把\L和\E之间的字符转换为小写
\U 把\L和\E之间的字符转换为大写
\l 把下一个字符转换为小写
\u 把下一个字符转换为大写
按位置引用 (从 \1 开始计数)
<[hH]([1-6])>.*</[Hh]\1>
命名引用
回溯引用跨模式替换
8. 前后查找
正向前查找 (?=) https://www.baidu.com .+(?=:) http
正向后查找 (?<=) ABC01: $122.12 (?<=\$)[0-9.]+ 122.12
负向前查找(向前查找不与给定模式相匹配的文本) (?!)
负向后查找(向后查找不与给定模式相匹配的文本) (?<!) I pid $30 for 100 apples \b(?<!\$)\d+\b 100 //如果不加\b边界的话,$30中的0也会被匹配
9. 嵌入条件
(并非所有的正则表达式实现都支持条件处理,vim就不支持)
? 匹配前一个字符或表达式--如果它存在的话
?=和?<= 匹配前面或后面的文本--如果它存在的话
回溯引用条件: 只在一个前面的表达式搜索取得成功的情况下才允许使用一个表达式
语法:?(backreference)true-regex|false-regex
?,表明这是一个条件
括号里的backreference是一个回溯引用,是子表达式标号
true-regex是一个只有在backreference存在时才会被执行的子表达式
false-regex是一个只有在backreference不存在时才会被执行的子表达式
(<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa]>)
(<[Aa]\s+[^>]+>\s*)?,匹配一个<A>或这<a>标签及其任意属性。?说明了这个标签可有可无
<[Ii][Mm][Gg]\s+[^>]+>,匹配一个<IMG>标签(大小写均可)及其任意属性
(?(1)\s*</[Aa]>),这是一个回溯引用条件,?(1)的意思是:如果第一个回溯引用(这里就是<A>标签)存在,则使用后面的表达式(\s*</[Aa]>)进行匹配
前后查找条件: 只在一个向前查找或向后查找操作取得成功的情况下才允许一个表达式被使用
语法:?(condition)true-regex|false-regex
\d{5}(?(?=-)-\d{4})
\d{5},这个很简单,就是匹配5个数字
(?(?=-)-\d{4}) 第一个?,表明这是一个前后查找条件,?=-匹配一个连字符‘-’,但不消费,如果条件得到满足(匹配到连字符),那么-\d{4}将匹配那个连字符后随后的4位数字
正则表达式引擎:
NFA(Deterministic finite automaton 非确定型有穷自动机): 表达式主导
传统NFA(Traditional NFA):
捕获组、反向引用和$number引用方式;
环视(Lookaround,(?<=…)、(?<!…)、(?=…)、(?!…)),或者有的有文章叫做预搜索;
忽略优化量词(??、*?、+?、{m,n}?、{m,}?),或者有的文章叫做非贪婪模式;
占有优先量词(?+、*+、++、{m,n}+、{m,}+,目前仅Java和PCRE支持),固化分组(?>…)。
POSIX NFA:
符合POSIX标准的NFA引擎,它的特点主要是提供longest-leftmost匹配,也就是在找到最左侧最长匹配之前,它将继续回溯。同DFA一样,非贪婪模式或者说忽略优先量词对于POSIX NFA同样是没有意义的
DFA(Deterministic finite automaton 确定型有穷自动机): 文本主导
不需要回溯,所以匹配快速,但不支持捕获组,所以也就不支持反向引用和$number这种引用方式 不支持忽略优先
以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章