正则表达式简介
来源:互联网 发布:安卓优化软件排行榜 编辑:程序博客网 时间:2024/04/30 18:26
什么是正则表达式
正则表达式也叫做匹配模式(Pattern),它由一组具有特定含义的字符串组成,通常用于匹配和替换文本。
正则表达式看上去并不像某种语言或者某个技术那么重要,仅靠正则你无法写出一个应用程序来。然后,它们总会出现在你的开发过程中,不管是进行表单验证,还是高亮显示搜索结果,又或是进行URL地址映射,总需要使用它们。几乎所有的语言都对它进行了不同程度的支持,由此足见正则表达式在文本匹配中的地位。
正则表达式的基本元素
- 普通字符(literal character) >普通字符包括大小写的字母和数字,如 “a” “1”
- 元字符(metacharacter) >元字符是一些具有特殊含义的字符,包括 \ ^ $ . | ? * + ( ) [ ] { }
转义字符(escape character) >转移字符用于将元字符转换为普通字符,比如,当我们需要匹配字符”\”时,对应的正则表达式为”\ \”
预备知识字符串组成
对于字符串”abc”而言,包括三个字符和四个位置
占有字符和零宽度
正则表达式匹配过程中,如果子表达式匹配到的是字符内容,而非位置,并被保存到最终的匹配结果中,那么就认为这个子表达式是占有字符的;如果子表达式匹配的仅仅是位置,或者匹配的内容并不保存到最终的匹配结果中,那么就认为这个子表达式是零宽度的。
占有字符是互斥的,零宽度是非互斥的。也就是一个字符,同一时间只能由一个子表达式匹配,而一个位置,却可以同时由多个零宽度的子表达式匹配。
- #### 控制权和传动
正则的匹配过程,通常情况下都是由一个子表达式(可能为一个普通字符、元字符或元字符序列组成)取得控制权,从字符串的某一位置开始尝试匹配,一个子表达式开始尝试匹配的位置,是从前一子表达匹配成功的结束位置开始的。
如正则表达式:(子表达式一)(子表达式二)
假设(子表达式一)为零宽度表达式,由于它匹配开始和结束的位置是同一个,如位置0,那么(子表达式二)是从位置0开始尝试匹配的。
假设(子表达式一)为占有字符的表达式,由于它匹配开始和结束的位置不是同一个,如匹配成功开始于位置0,结束于位置2,那么(子表达式二)是从位置2开始尝试匹配的。
而对于整个表达式来说,通常是由字符串位置0开始尝试匹配的。如果在位置0开始的尝试,匹配到字符串某一位置时整个表达式匹配失败,那么引擎会使正则向前传动,整个表达式从位置1开始重新尝试匹配,依此类推,直到报告匹配成功或尝试到最后一个位置后报告匹配失败。
- #### 匹配过程例子1:
源字符串:abc
正则表达式:abc
匹配过程:
首先由字符“a”取得控制权,从位置0开始匹配,由“a”来匹配“a”,匹配成功,控制权交给字符“b”;由于“a”已被“a”匹配,所以“b”从位置1开始尝试匹配,由“b”来匹配“b”,匹配成功,控制权交给“c”;由“c”来匹配“c”,匹配成功。
此时正则表达式匹配完成,报告匹配成功。匹配结果为“abc”,开始位置为0,结束位置为3。
- #### 匹配过程例子2:
源字符串:abd
正则表达式:ab?c
匹配过程:
首先由字符“a”取得控制权,从位置0开始匹配,由“a”来匹配“a”,匹配成功,控制权交给字符“b?”;先尝试进行匹配,由“b?”来匹配“b”,同时记录一个备选状态,匹配成功,控制权交给“c”;由“c”来匹配“d”,匹配失败,此时进行回溯,找到记录的备选状态,“b?”忽略匹配,即“b?”不匹配“b”,让出控制权,把控制权交给“c”;由“c”来匹配“b”,匹配失败。此时第一轮匹配尝试失败。
正则引擎使正则向前传动,由位置1开始尝试匹配,由“a”来匹配“b”,匹配失败,没有备选状态,第二轮匹配尝试失败。
继续向前传动,直到在位置3尝试匹配失败,匹配结束。此时报告整个表达式匹配失败。
- #### 匹配过程例子3:
源字符串:a12
正则表达式:?=[a-z][a-z0-9]+$
元字符“”和“$”匹配的只是位置,顺序环视“(?=[a-z])”只进行匹配,并不占有字符,也不将匹配的内容保存到最终的匹配结果,所以都是零宽度的。
这个正则的意义就是匹配由字母和数字组成的,第一个字符是字母的字符串。
匹配过程:
首先由元字符“”取得控制权,从位置0开始匹配,“”匹配的就是开始位置“位置0”,匹配成功,控制权交给顺序环视“(?=[a-z])”;
“(?=[a-z])”要求它所在位置右侧必须是字母才能匹配成功,零宽度的子表达式之间是不互斥的,即同一个位置可以同时由多个零宽度子表达式匹配,所以它也是从位置0尝试进行匹配,位置0的右侧是字符“a”,符合要求,匹配成功,控制权交给“[a-z0-9]+”;
因为“(?=[a-z])”只进行匹配,并不将匹配到的内容保存到最后结果,并且“(?=[a-z])”匹配成功的位置是位置0,所以“[a-z0-9]+”也是从位置0开始尝试匹配的,“[a-z0-9]+”首先尝试匹配“a”,匹配成功,继续尝试匹配,可以成功匹配接下来的“1”和“2”,此时已经匹配到位置3,位置3的右侧已没有字符,这时会把控制权交给“$”;
元字符“$”从位置3开始尝试匹配,它匹配的是结束位置,也就是“位置3”,匹配成功。
此时正则表达式匹配完成,报告匹配成功。匹配结果为“a12”,开始位置为0,结束位置为3。其中“”匹配位置0,“(?=[a-z])”匹配位置0,“[a-z0-9]+”匹配字符串“a12”,“$”匹配位置3。
基本语法
1.匹配固定字符
Text: artificial intelligence
Regex: i
Text: Instead of crying, I shouted hello world on my birth.
Regex: hello
2.匹配任意单个字符(用元字符 .)
Text: regular.doc regular1.exe regular2.dat expression.doc express.dat
Regex: regular.
Regex: .e..
3.匹配元字符 . 本身
Text: regular.exe regular1.exe
Regex: r.
4.匹配字符组
有时候我们只希望匹配某几个字符中的一个,比如,我们要匹配”head”, “heat”这两个单词中的一个。正则提供了字符组来解决这个问题,它的语法是”[dt]”
Text:bread heay head heat
Regex: hea[td]
5.在字符组中使用字符区间
“[012…9]” —–> “[0-9]”
“[0123]” —–> “[0-3]”
“[abc…z]” —–> “[a-z]”
“[bcde]” —–> “[b-e]”
“[CDE]” —–> “[C-E]”
这个区间的起始字符和结束字符是依据ASCII值的大小,匹配ASCII码位于起始字符和结束字符之间的所有字符。
6.反义字符组
匹配除了字符集合意外的字符。语法是”[字符集合]”
如[1-3]
7.匹配特殊字符
- ##### 匹配元字符
元字符 匹配方式 \ \ \ ^ \ ^ - ##### 匹配空字符
匹配方式 描述 \f 换页符 \n 换行符 \r 回车符 \t 制表符 \v 垂直制表符
8.预定义字符
匹配方式 描述 . 任何字符 \d 数字 \D 非数字 \s 空白字符 \S 非空白字符 \w 单词字符 \W 非单词字符
9.量词
贪婪 惰性 描述 X? X?? 匹配 X 零次或一次 X* X*? 匹配 X 零次或多次 X+ X+? 匹配 X 一次或多次 X{n} X{n}? 匹配 X n 次 X{n,} X{n,}? 匹配 X 至少 n 次 X{n,m} X{n,m}? 匹配 X 至少 n 次,但不多于 m 次
场景:找到html里面所有加粗的文本
Text: Jimmy is a junior developer in shanghai.
Regex: .*
Regex: .*?
场景: 将量词应用于子表达式
Text: catcatcatcat
Regex: cat{3}
Regex: (cat){3}
10 边界匹配
匹配单词的首末
Text: The cat scattered its food all over the room.
Regex: \bcat
Regex: cat\b
Regex: \bcat\b
边界的相对性
Text: The cat s-cat-tered its food all over the room.
Regex: \bcat\b
结论:
- 当你对一个普通字符(如”s”)设置边界,它的边界是空格、分隔符、逗号、句号等
- 当你对一个边界字符(如”-“)设置边界,它的边界是普通字符
匹配文本的首末
- “”用于匹配文本首
- “$”用于匹配文本末
Text: city1 city2 city3
Regex: city\d?
Regex: city\d?$
11 后向引用
场景:去除重复出现的”of”和”up”
Text: The cost of of gas goes up up.
Regex: (of|up) (of|up)
Text: The cost of up.
Regex: (of|up) (of|up)
Text: The cost of up of of up up.
Regex: (of|up) \1
这里的\1相当于获取分组1对应的模式的内容,假如匹配时,模式是of,那\1就代表of。
分组
分组是通过从左往右计算开括号进行编号的。
比如:对于正则表达式((A)(B(C))),有以下4个分组
1. ((A)(B(C)))
2. (A)
3. (B(C))
4. (C)
后向引用一个常见的应用是匹配有效的html标签。
Text: bla bla bla
bla bla bla
Regex: .*?
12 环视(非获取匹配)
(?=Pattern) —-> 当前位置右边满足Pattern
(?!Pattern) —-> 当前位置右边不满足Pattern
(?
- 正则表达式简介 (转)
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 基本正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介
- 正则表达式简介1
- linux正则表达式简介
- 正则表达式 简介
- java正则表达式简介
- Python:正则表达式简介
- A+B for Input-Output Practice (II)
- 新的开始
- 1135降序排序
- 2017.3.13 E
- android使用方法---图片的高斯模糊
- 正则表达式简介
- 1134求最大值
- 数据结构-从归并排序到数组的逆序对数(微软面试题)
- ResultSet类—结果集容易忽略的问题
- 1056这道题不能做
- 一个使用纯Win32 SDK和C语言实现的五子棋游戏
- 创建型模式-生成器(builder)
- leetcode_14. Longest Common Prefix
- Android应用层View绘制流程与源码分析