大家好,关于深入浅出正则表达式基础教程(一)很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
正则表达式
正则表达式是用于描述一定量文本的模式。
RegEx 代表常规快递
正则表达式引擎
是一个可以处理正则表达式的软件(通常引擎是较大应用程序的一部分)
本教程重点介绍使用最广泛的Perl 5 类型引擎。比较与其他发动机的差异。
现代引擎类似但不完全相同,例如.NET正则库JDK正则包
文字符号
最简单的正则表达式由单个文字符号组成。
例如,a 将匹配字符串中第一次出现的字符a。
匹配字符串Jack 是一个男孩。
结果:J后的a将被匹配。而第二个a将不会被 匹配。正则表达式也可以匹配第二个a。这必须通过告诉正则表达式引擎从第一个匹配点开始搜索来完成。
(相当于文本编辑器中查找next。也相当于编程中有一个从上一个匹配位置开始继续向后查找的功能。)
cat 将匹配“关于猫和狗”中的cat。
等于告诉正则表达式引擎:
找到一个c,后面跟着一个a,后面跟着一个t
正则表达式引擎默认大小写敏感cat 不会匹配Cat,除非您告诉引擎忽略大小写。
元字符(metacharacter)
对于文字字符,保留12 个字符用于特殊用途,即元字符:
[ ]^$。 |? *+ ()
在正则表达式中,如果要将这些字符用作没有特殊含义的文本字符
用反斜杠转义它
例如
表达式为1+1=2
匹配1+1=2
注意正则表达式1+1=2有效+表示从1到多次重复
它不会匹配文本1+1=2
将匹配文本中的111=2 123+111=234
在编程语言中,一些特殊字符首先由编译器处理,然后传递给正则引擎。
#因此正则表达式
1+2=2
#用C++编写
1\+1=2#为了匹配文本C:temp
#正则表达式C:\temp
#C++中的正则表达式C:\\temp
不可显示字符
一些不可显示的字符使用其对应的特殊字符序列
t选项卡0x09
r 回车符0x0D
n 换行符0x0A
注意
在Windows 中,文本文件以rn 结尾
Unix 用法n
正则表达式引擎的内部工作机制
正则表达式引擎的工作原理可以帮助您快速了解为什么某个正则表达式不能按您期望的方式工作。
有2种类型的引擎:文本导向引擎正则导向引擎(正则表达式导向引擎(目前最流行,本文讲的是正则表达式导向引擎)) Jeffrey Friedl 将它们称为DFA 和NFA 引擎。
因为一些非常有用的功能只能在面向常规的引擎:中实现
喜欢
惰性量词
反向引用
通过测试确定某个引擎是面向文本/面向常规的引擎:
如果实现了反向引用或惰性量词,那么引擎必须是面向正则表达式的
正则表达式regex|regex not
匹配字符串正则表达式not 并得到结果:
1regex 的结果并不是引擎是面向文本的。
2regex 的结果是引擎是面向正则的。正则导向的引擎总是很急切地报告它找到的第一个匹配
正则导向的引擎 -急切的返回第1个(即最左边)匹配结果
这是您需要了解的重要一点。即使稍后可能找到更好的匹配,面向正则表达式的引擎也将始终返回最左边的匹配。
例子
正则表达式猫
文本他为他的猫捕获了一条鲶鱼
详细匹配流程:
引擎首先比较正则表达式符号c和H,匹配失败;
于是引擎接着比较正则表达式符号c和e,匹配失败;
.直到匹配到第4个字符c,则匹配成功;
正则表达式符号a匹配第五个字符a,匹配成功;
第六个字符t匹配p,匹配失败;
引擎继续从第5 个字符开始重新检查匹配
.直到第15个字符开始,cat与catfish中的cat匹配
就是这样。正则表达式引擎急切返回第1个匹配结果,而不会再继续向后查找(无论是否有其他文本可以被匹配
字符集
字符集是由一对方括号[] 括起来的字符集。
使用字符集告诉正则表达式引擎仅匹配多个字符之一。
使用正则表达式[ae]
匹配a 或e
字符集中的字符顺序并没有意义,结果都是相同的。为
使用正则表达式gr[ae]y 或等效的gr[ea]y
两者都匹配灰色或灰色(如果您不确定要匹配的文本是否是美国/英国英语,则特别有用)
两者都不会匹配graay 或graey
使用连字符集定义字符范围(例如字符集[0-9])来匹配0 到9 之间的单个数字。
使用多个范围的字符集
喜欢
匹配单个十六进制字符且不区分大小写
[0-9a-fA-F]
使用两者:将范围定义与单个字符定义结合起来
例子
[0-9a-fxA-FX]
喜欢
匹配不区分大小写的单个十六进制字符,或字符X
再次强调,字符和范围定义的先后顺序 对结果没有影响。
字符集的一些应用
查找可能拼写错误的单词
例如,sep[ae]r[ae]te 或li[cs]en[cs]e
查找编程语言的标识符
A-Za-z_][A-Za-z_0-9]*
* 表示重复0次或多次
查找C 风格的十六进制数字
0[xX][A-Fa-f0-9]+
+ 表示重复(前一个字符或表达式)一次或无限次
取反字符集
紧跟在左方括号[ 后面的^ 将反转字符集,以便正则表达式表示形式将匹配方括号中的任何不在字符。
注意 取反字符集一定会要 匹配一个字符,可以匹配回车换行符示例1
匹配q 后跟u 以外的字符
正则表达式q[^u]
文本
ffffq
ffff结果
q 和换行符(非u 字符、回车符和换行符是匹配结果的一部分)
实施例2
正则表达式:q[^u]
文字:伊拉克
没有找到匹配的结果
因为q后面没有字符!单个q不会被匹配如果只想在某些条件下匹配q 字符,例如仅在q 后面跟有非u 字符时才匹配q 字符,请使用后面提到的向前查看。
字符集中的元字符
注意字符集中只有4个元字符】^-
] 代表字符集定义结束
代表转义
^ 代表否定
- 表示除这4个元字符之外的其他常见元字符的范围定义。它们都是字符集定义内的文本字符,不需要转义。 (如果你转义那些常见的元字符,正则表达式仍然有效。很好,但会降低人类可读性)
例如,要匹配文本星号* 或加号+
正则表达式[+*] 在字符集定义中,为了将反斜杠视为字面字符而不是有特殊含义的字符,需要用另一个反斜杠对其进行转义。
正则表达式[\x]
将匹配文本x 元字符]^- 可以用反斜杠转义,或者放置在无法使用其特殊含义的位置(这样可以增加可读性)
例如,如果将字符^放在非左括号[之后的位置,则将使用文本字符的含义而不是否定含义。
喜欢
[x^] 将匹配字符x 或^
[]x] 将匹配字符] 或x
[-x] 或[x-] 将匹配1 或x
字符集的简写【记忆】
非常常用的字符集有缩写
d 代表数字[0-9]
w 表示单词字符,根据正则表达式的实现不同,存在一些差异。大多数正则表达式实现的单词字符集包括A-Za-z0-9_
s 代表空白字符
根据正则表达式的实现,存在一些差异。在大多数实现中,包括空格字符、制表符以及回车符和换行符rn。
方括号内外都可以使用字符集的缩写。
sd 匹配单个白色字符后跟一个数字
[sd] 匹配单个白色字符或数字
[da-fA-F] 匹配十六进制数
反转字符集的缩写形式
[S] 是[^s]
[W]即[^w]
[D] 是[^d]
字符集的重复
如果使用?*+运算符重复字符集,则整个字符集将被重复(而不是其匹配的字符)
例子
正则表达式[0-9]+
将匹配文本837 和222
如果只想重复匹配的字符,可以使用向后引用。稍后再说
使用?*或+ 进行重复
?
告诉引擎匹配前导字符0 次或一次。事实上,这意味着主角是可选的。
告诉引擎匹配主角1 次或多次
告诉引擎匹配前导字符0 次或多次
例子
[A-Za-z][A-Za-z0-9]* 匹配不带属性和文字符号的HTML 标记。
第一字符集匹配字母,第二字符集匹配字母或数字。
意思是匹配前导字符0次或者无数次,0次就可以匹配这样的标签。看来我们也可以使用正则表达式[A-Za-z0-9]+
但它会匹配1
限制重复次数
前导子表达式重复多少次语法{min,max}
min 和max 都是非负整数(整数min=0,整数max=0)
实施例1
{0,1} 对于前导子表达式重复0 或1 次
{1}重复前导子表达式一次。如果逗号和max 都被省略,则重复min 次。
{0,}相当于有一个逗号,不写最大值,表示最大值无穷大。
{1,} 相当于+
实施例2
正则表达式zo+可以匹配zo和zoo。但它不能匹配z。
正则表达式b[1-9][0-9]{3}b(b代表字边界)
匹配1000~9999 之间的数字。
正则表达式b[1-9][0-9]{2,4}b
匹配100 到99999 之间的数字。
注意: 懒惰指匹配结果尽可能短、贪婪是匹配结果尽可能长
懒?匹配尽可能短的文本
贪心+ 匹配尽可能长的文本
例子
将HTML 标记与正则表达式进行匹配。
输入一个正常有效的HTML文件(不需要排除无效标签),所以如果是两个尖括号之间的内容,那么它应该是一个HTML标签。
贪婪的正则表达式.+匹配结果尽可能长
很多新手都用表达式+
测试字符串这是第一个测试
先得到匹配结果显然不是我们想要的结果。
我们期望得到的结果继续匹配得到
因为+是贪婪的 即匹配尽量长的文本!+ 会导致正则表达式引擎尝试尽可能重复其前面的字符(只有当这种重复会导致整个正则表达式失败时,引擎才会回溯,即放弃最后一次重复,然后处理正则表达式的其余部分)
与+ 类似,重复?* 也是贪婪的。
详细匹配过程:匹配字符,匹配成功;
.匹配字符E,匹配成功;
+重复前面的(表达式符号),即表达式。点符号可以匹配下一个字符,直到遇到换行符。如果换行符不匹配,则匹配失败,即+match失败;
此时已经匹配到的文本是firsttest
引擎匹配正则表达式的最后一个符号,并尝试匹配换行符,但匹配失败;
此时已经匹配到的文本是firsttest
表达式的最后一个符号也匹配失败,引擎回溯(从向后匹配变为向前匹配)
尝试匹配t,匹配失败;
继续向前匹配,继续失败.
直到遇到first后面的字符,匹配成功!
第一个匹配结果是
第一的
正则导向的引擎是急切的,所以它会急于报告它找到的第一个匹配项。而不是继续回溯(所以没有找到匹配)
可见+的贪婪本质使得正则表达式引擎能够获得“最长”的匹配结果。
可行方案1 使用“懒惰的”正则表达式.+?匹配标签
+ 之后紧接着一个问号?实现惰性(匹配尽可能短的文本)
类似的解决方案可以用于*``{}``? 表示的重复。变贪婪为懒惰,匹配尽可能短的文本。
?匹配尽可能短的文本
+?匹配尽量短的文本!实现了"懒惰性" 带上问号的+是懒惰的!+为了尽可能少地重复前一个字符。因此匹配成功后立即使用下一个正则表达式符号进行匹配。
正则表达式.+?详细匹配流程:
正则表达式符号。匹配文本中的下一个字符E,匹配成功;
懒+?为了尽快得到匹配结果,使用下一个正则表达式符号来匹配文本中的下一个字符M。匹配失败(引擎回溯)
使用前一个正则表达式字符来匹配当前字符M,匹配成功;
此时正则表达式进行到.+
此时已经匹配到的文字为
懒+?为了尽快得到匹配结果,立即使用下一个正则表达式符号去匹配文本中的下一个字符,匹配成功;
正则表达式结束
引擎报告已获得成功的匹配
更好的替代方案:取反字符集
规律性发动机
使用否定字符集后跟贪婪重复加号[^]+
之所以这是一个更好的解决方案,是因为使用否定字符集不需要回溯。
当使用惰性重复时,引擎将回溯每个字符,然后找到成功的匹配。和
使用.匹配任意字符 (除了换行符)
在正则表达式中。是最常用且最容易误用的符号。
.匹配任意单个字符(仅不匹配换行符)
默认情况下,本教程中讨论的引擎都不匹配换行符。
默认。相当于
字符集[^nr](Windows)
字符集[^n](Unix)
由于历史原因,换行符不匹配:
早期使用正则表达式的工具是基于行的。它们都逐行读取文件,并对每一行分别应用正则表达式。
所以每一行的字符串中当然没有换行符。
所以。不匹配换行符。
现代工具和语言可以将正则表达式应用于非常大的字符串,甚至整个文件,并且所有正则表达式实现都提供了让.匹配所有字符(包括换行符)。
在RegexBuddy、EditPad Pro 或PowerGREP 等工具中,您只需选择句点来匹配换行符即可。
在Perl 中,匹配换行符的模式称为单行模式,这是一个令人困惑的术语。因为还有多线模式。
多行模式仅影响行首和行尾的锚点,而单行模式仅影响.
其他语言和正则表达式库都采用了Perl的术语定义。
在.NET Framework 中使用正则表达式类时,可以使用类似于以下的语句激活单行模式:
Regex.Match(字符串,正则表达式,RegexOptions.SingleLine)
强大的点号.
点可以说是最强大的元字符:有了点,它几乎可以匹配任何字符。
问题是它经常匹配不应该匹配的字符!
例子
匹配mm/dd/yy 格式的月/日/年日期
允许用户选择分隔符。
不可行的方案1
dd.dd.dd
它匹配日期02/12/03
问题是02512703也会匹配到
不可行的方案2
dd[-/.]dd[-/.]dd
稍微好一点,支持3种分隔符。
(点在字符集中,不用作元字符)
这个解决方案远非完美,它将匹配99/99/99
选项3
[0-1]d[-/.][0-3]d[-/.]dd
更好,但会匹配19/39/99
.
如果你想验证用户输入,它需要尽可能完美。
如果您只想分析已知来源,并且我们知道没有错误数据,那么与您要搜索的字符相匹配的良好正则表达式就足够了。
字符串开始的锚定^ 和 结束的锚定$
锚点与一般正则表达式符号不同。锚点不匹配任何字符。
锚点匹配字符之前或之后的位置。正则表达式^ 将匹配一行字符串的第一个字符之前的位置。
正则表达式^a 将匹配字符串abc 中的a
正则表达式^b不会匹配abc中的任何字符
类似地,$匹配字符串中最后一个字符之后的位置
#正则表达式
加元
#匹配文本abc
锚定的应用
中的c 在编程语言中使用锚点验证用户输入非常重要
使用正则表达式^d+$ 验证用户输入是否为整数
匹配用户输入中经常出现的额外前导或尾随空格
^s* 匹配字符串之前的空格
s*$ 匹配字符串末尾的空格
如果您有一个包含多行的字符串,例如
第一行nr第二行
(其中nr代表换行符)
通常您需要处理行,而不是整个字符串。
几乎所有正则表达式引擎都提供了扩展这两个锚点含义的选项。
^ 可以匹配字符串的开头(f之前)和每个换行符后面的位置(这个位置在nr和s之间)
$ 将匹配字符串的结尾(最后一个e 之后)和每个换行符之前的位置(该位置在e 和nr 之间)
使用以下代码在.NET 中定义锚定,匹配每个换行符之前和之后的位置:
Regex.Match("string", "regex", RegexOptions.Multiline) 示例
在每行的开头插入文本字符
string str=Regex.Replace(Original, "^", "", RegexOptions.Multiline)
绝对锚定
A 只匹配整个字符串的开头
Z 只匹配整个字符串的结尾
即使你使用多行模式,这两个也永远不会匹配换行符。
例外
如果字符串以换行符结尾,Z 和$ 将匹配这个最后的换行符前面的位置而不是整个字符串的结尾。
这种改进是由Perl 引入的,随后出现了许多正则表达式实现,包括Java、NET 等。
【深入浅出正则表达式基础教程(一)】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于开始学习正则表达式的文章啦!
有19位网友表示赞同!
期待深入了解正则表达式的原理和使用方法!
有19位网友表示赞同!
我一直对正则表达式比较好奇,希望这篇文章能解释清楚。
有10位网友表示赞同!
想学好编程真的离不开正则表达式这个工具啊
有20位网友表示赞同!
看来要好好review一下正则表达式的内容了
有5位网友表示赞同!
学习正则表达式的过程中容易遇到瓶颈,希望能找到解决方法。
有13位网友表示赞同!
希望这篇文章能提供一些实用技巧
有6位网友表示赞同!
我想要了解如何在实际应用中使用正则表达式
有7位网友表示赞同!
刚开始接触正则表达式,感觉还挺复杂的
有15位网友表示赞同!
看完这篇文章后,希望能用正则表达式解决一些文本处理问题
有19位网友表示赞同!
文章结构清晰易懂?期待接下来的讲解!
有7位网友表示赞同!
学习编程就是需要不断积累工具, 正则表达式也不例外
有13位网友表示赞同!
正则表达式应用范围非常广啊!
有14位网友表示赞同!
感觉学习正则表达式很有成就感,可以解决很多问题!
有8位网友表示赞同!
分享一些经验和技巧会更有帮助
有17位网友表示赞同!
这篇文章是学习正则表达式的入门指南吗?
有16位网友表示赞同!
希望文章能提供一些练习题或案例分析
有14位网友表示赞同!
期待看到更多关于正则表达式高级应用的讲解!
有16位网友表示赞同!