Regular Expression-正则表达式(二)

上一篇文章已经就正则表达式的各类字符的使用范围和功能做了一些简介,本文就实际的匹配操作做一下介绍,本文用到的正则表达式字符上文的表都能查到,不熟的可以对照看。

先介绍一下正则匹配的两个引擎,NFA和DFA

NFA(Nondeterministic Finite Automata)不确定的有穷自动机

1.一个有穷的状态集合SS={0,1,2,3})

2.一个输入符号集合Σ Σ ={a,b})

3.转换函数,对于每个状态和Σ∪{ε}中的符号,给出相应的后继状态的集合

(0,a)→{0,1} (0,b)→{0} (1,b)→{2} (2,b)→{3}

4.S中的某个状态s0被指定为开始状态/初始状态( s0 是0)

5.S的一个子集F被指定为接受状态集合(F为{3})

DFA(Deterministic Finite Automata)确定的有穷自动机,某个NFA就被称为DFA

1.没有标号为ε的转换

2.对于每个状态s和每个输入符号a,有且仅有一条标号为a的离开s的边

3.可以高效判断一个串能否被一个DFA接受

4.每个NFA都有一个等价的DFA

以上内容来源于编译原理,还没开始深入学习编程语言,初看编译原理还是很难理解的,我也是为了学习正则表达式凑合看了下,后面有机会再介绍吧。

学习正则表达式,普通字符,各种元字符总是很难记忆,最好的方法当然是熟能生巧,但是日常工作并不一定很常用,这时候记一下分类就好了。

匹配单个字符(字符本身、【.】点号、【[0-9a-zA-Z_]】字符组、【\*】等元字符本身、【\s】等特定字符类型)

匹配不固定数目字符(【+】一个或多个、【*】零个或者多个、【?】零个或者一个、【{m,n}】指定数目字符)

贪婪匹配和惰性匹配(默认贪婪匹配,即最长匹配,惰性匹配在匹配不固定数目字符类的符号后面加【?】)

匹配边界(【\b】边界、【\B】非边界、【^】开头、【$】结尾)

子模式(【()】括号内的正则表达式是一个整体)

 

一、匹配单个字符

1.匹配固定单个字符

所有的单个大小写字母、数字以及上面出现过的特殊字符经过转义后,都是一个正则表达式,都可以严格匹配字符自身。

【Text】Jimmy is a junior developer and jimmy lives in xi’an.

【RegEx】i

【Result】Jimmy is a junior developer and jimmy lives in xi’an.

2.匹配任意单个字符

【.】可以匹配任意单个字符,英文字母、数字、下划线以及其自身(不匹配换行符)。

【Text】regular.doc regular1.exe regular2.dat expression.doc express.dat

【RegEx】regular.

【Result】regular.doc regular1.exe regular2.dat expression.doc express.dat

3.匹配字符组

【.】在匹配的时候过于灵活,几乎可以匹配所有的单个字符,如果只希望匹配有限字符中的某一个,就可以使用字符组了,前述表中的【[]】元字符可以实现。

【Text】bread heay teas head heat

【RegEx】.ea[td]

【Result】bread heay teas head heat

如果匹配的量很大,每一个字符都写全的话会显得很臃肿,这时候就可以结合【-】字符,使用字符区间,但是需要注意字符顺序不能颠倒,比如数字【[0123456789]】可以用【[0-9]】代替,【[0-9a-zA-Z]】表示所有的数字和大小写字母

【Text】city.jpg city0.jpg city1.jpg city2.jpg city3.jpg city4.jpg

【RegEx】city[1-3]\.jpg

【Result】city.jpg city0.jpg city1.jpg city2.jpg city3.jpg city4.jpg

有时候除了选取我们需要的字符,还会有除了某些字符以外的其他字符这样的匹配需求,这时候就要使用取反字符【^】,需要强调的是【^】必须在【[]】内部,在外部的话就会是开头的意义了。

【Text】city.jpg city0.jpg city1.jpg city2.jpg city3.jpg city4.jpg

【RegEx】city[^1-3]\.jpg

【Result】city.jpg city0.jpg city1.jpg city2.jpg city3.jpg city4.jpg

4.匹配特殊字符

4.1匹配元字符

元字符在之前的实例中已经遇到过,元字符在正则表达式中具有特殊含义的字符,如前面列表中的【.】【*】【\】【[]】【{}】【+】【?】【{}】【^】【$】等,具体作用可查前表。

【Text】City[0].Name = "Xian" City[0]_Name = "Shanghai" City0.Name = "Hangzhou" City0_Name = "Beijing"

【RegEx】City[0].name

【Result】City[0].Name = "Xian" City[0]_Name = "Shanghai" City0.Name = "Hangzhou" City0_Name = "Beijing"

4.2匹配特定字符类型

刚刚的元字符在加【\】符号之后就会显示正常,还有一类字符是普通字符,但是在加了【\】之后就会显示特殊含义,这类字符就包括【\r】回车符、【\n】换行符、【\t】横向制表符、【\v】垂直制表符、【\f】换页符等空白字符,也包括【\d】数字字符、【\D】非数字字符、【\w】所有大小写数字和下划线、【\W】所有非大小写数字和下划线字符、【\b】边界字符、【\B】非边界字符、【\s】空白字符、【\S】非空白字符

【Text】abcde 12345 a1b2c abcd 1234

【RegEx】\w\d\w\d\w

【Result】 abcde 12345 a1b2c abcd 1234

二、匹配多个字符
1.匹配一个或多个

单个字符匹配,不管是字符、字符范围、字符类型都只匹配一个字符,有n个正则表达式匹配n个字符,如【[0-3][0-3]】匹配两个0-3的数字,需要匹配多个数字字符串的时候就比较冗长,可以用【+】来实现,【+】代表匹配前一个字符一个或者多个。

【Text】jimmy jjjimmy simmy immy enjoy enjjoy

【RegEx】j+

【Result】jimmy jjjimmy simmy immy enjoy enjjoy

2.匹配零个或多个

【*】和【+】功能类似,【*】可以匹配零个或者多个前面的字符

【Text】I like city.jpg、city1.jpg、city365.jpg most, I suppose cityss.jpg and city_1.jpg are the worst ones.

【RegEx】city\d*\.jpg

【Result】I like city.jpg、city1.jpg、city365.jpg most, I suppose cityss.jpg and city_1.jpg are the worst ones.

3.匹配零个或一个

【?】匹配零个或者一个前面的字符

【Text】These flowers are very beautiful, hope you like them. This flower is so beautiful, seems like smiling to you.

【RegEx】flowers?

【Result】These flowers are very beautiful, hope you like them. This flower is so beautiful, seems like smiling to you.

4.匹配指定个数

【+】【*】【?】能匹配零个、一个和不定个数的字符,但是类似指定7个字符个数的匹配无法完成,需要结合【{m,n}】来制定匹配字符的个数的数目范围,【m】代表下线个数,【n】代表上线个数

【Text】0、10、111、001、789、1234 are all matched numbers.

【RegEx】\d{1,3}

【Result】0、10、111、001、789、1234 are all matched numbers.

三、贪婪匹配和惰性匹配

贪婪匹配

        它会匹配尽可能多的字符。它首先看整个字符串,如果不匹配,对字符串进行收缩;遇到可能匹配的文本,停止收缩,对文本进行扩展,当发现匹配的文本时,它不着急将该匹配保存到匹配集合中,而是对文本继续扩展,直到无法继续匹配 或者 扩展完整个字符串,然后将前面最后一个符合匹配的文本(也是最长的)保存起来到匹配集合中。所以说它是贪婪的

惰性匹配

它会匹配尽可能少的字符,它从第一个字符开始找起,一旦符合条件,立刻保存到匹配集合中,然后继续进行查找。所以说它是懒惰的。

【Text】Jimmy is a <b>junior</b> developer <b>living</b> in <b>xi'an</c>

【RegEx】<b>.*</b>

【Result】Jimmy is a <b>junior</b> developer <b>living</b> in <b>xi'an</c>

贪婪匹配 惰性匹配 匹配描述
? ?? 匹配0个或者1个
+ +? 匹配1个或者多个
* *? 匹配0个或者多个
{m,n} {m,n}? 匹配n到m个

【Text】Jimmy is a <b>junior</b> developer <b>living</b> in <b>xi'an</c>

【RegEx】<b>.*?</b>

【Result】Jimmy is a <b>junior</b> developer <b>living</b> in <b>xi'an</c>

四、匹配边界

1.匹配字符边界

上面已经提过了,【\b】和【\B】和匹配边界和非边界,比较常用的就是单独匹配字符串和匹配字符串中的部分内容。边界不仅仅是空格,还有段落首行、段落末尾、逗号、句号 等符号作为边界,值得注意的是,分隔符“-”也可以作为边界

【Text】How to catch the cat.

【RegEx】\bcat\b

【Result】How to catch the cat.

【Text】How to catch the cat.

【RegEx】cat\B

【Result】How to catch the cat.

2.匹配文本边界

和【\b】和【\B】和匹配字符边界和非边界不同的是,【^】和【$】匹配文本的行首和行末尾,两者的匹配范围可以认为是一小一大

【Text】city.jpg and city1.jpg are all beautiful pictures except city9.jpg

【RegEx】^city\d?\.jpg

【Result】city.jpg and city1.jpg are all beautiful pictures except city9.jpg

【Text】city.jpg and city1.jpg are all beautiful pictures except city9.jpg

【RegEx】city\d?\.jpg\s*$

【Result】city.jpg and city1.jpg are all beautiful pictures except city9.jpg

五、匹配子模式

在正则表达式中,可以使用【()】将模式中的子字符串括起来,以形成一个子模式。将子模式视为一个整体时,那么它就相当于一个单个字符。

【Text】This is the second line.<br><br/><br />. This is the third line.<br>>>>>

【RegEx】<br\s*/?>{2,}

【Result】This is the second line.<br><br/><br />. This is the third line.<br>>>>>

【Text】This is the second line.<br><br/><br />. This is the third line.<br>>>>>

【RegEx】(<br\s*/?>){2,}

【Result】This is the second line.<br><br/><br />. This is the third line.<br>>>>>

正则表达式还有一些更高级的使用方式,后向引用、文本替换和预查和非获取匹配,我用的也不是很熟练,就不献丑了,后续熟悉了再介绍吧。

以上的匹配例子来源于https://www.cnblogs.com/jimmyzhang/

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇