正则表达式学习

1 入门:元字符

表示解释
1..匹配除换行符以外的任意字符
2.\b元字符代表单词的开头或结尾
3.\d元字符代表任意数字
4.\w元字符匹配字母、数字、下划线、汉字
6.^元字符匹配字符串开始
7.$元字符匹配字符串结束
8.{5,12}限制条件重复5到12次
9.\ ,转义字符用来使用元字符本身
10.[aeiou]自定义元字符

举例:

1.查找hi后面不远处跟着一个Lucy \bhi\b.*\bLucy\b
2.精确查找’hi’ \bhi\b
3.搜索国内固定电话 0\d\d-\d\d\d\d\d\d\d\d
8.QQ只能输入5-12位数字 ^\d{5-12}$ 或者\b\d{5,12}\d
10.[aeiou]匹配所有元音字母,[0-9]==\d,[a-z0-9A-Z]==\w(只考虑英文)


入门:限定符(限定前面的内容)

限定符意义
*重复零次或更多次
+重复一次或更多次
重复零次或一次
{n}重复n次
{n,}重复n此或更多
{n,m}重复n到m次
  • 例子1:Windows\d+ 匹配windows后跟1个或多个数字 ^\w+ 匹配字符串中的第一个词
    \(?0\d{2}[) -]?\d{8} 理解:(?表示匹配0或1此( 0表示匹配0 \d{2}表示两个数字 [)
    -]?表示)空格-中匹配到任意一个或者不匹配 \d{8} 表示8个数字
    –>这样做的结果:好的 (010)88886666,或022-22334455,或02912345678
    不好的 010)12345678或(022-87654321

分枝条件|

和or类似,符合条件的都列出来,相比于单一限定条件,这样反而精确了,

例子1: 0\d{2}-\d{8}|0\d{3}-\d{7} 012-12345678 相比于\(?0\d{2}[) -]?\d{8},排除了上面几个不好的结果

例子2:\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8} 匹配到:(012)-12345678|012-12345678

***例子3:\d{5}-\d{4}|\d{5} 效果:12345-1234 匹配到12345
\d{5}-\d{5}-\d{4} 匹配12345-6789会是什么结果?12345

例子4:\d{5}-\d{4}|\d{5}匹配12345-6789结果?12345-6789
说明用|执行相互包含的条件时要把复杂条件写在前面,否则先匹配到简单的条件指针也不会自己再回头了,复杂的条件就匹配不到了


分组:()

小括号来指定表达式,类似于运算符中的效果,可以给限定条件指定前面的作用范围—

例3((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
分析:2[0-4]\d表示2+[1,2,3,4]+num 25[0-5]表示25+[0-5]两个是或的关系
[01]?\d\d?表示0或1取一位或不取+数字+数字取一位或不取 .表示接了一个. {3}表示前面括号中的内容重复三次后面括号里的内容和前面一样,只是ip地址中最后没有.了 所以这是匹配ip地址的正则表达式


反义:

符号意义
\W匹配非字母、数字、下划线、汉字的字符
\S匹配非空白符的字符
\D匹配非数字
\B匹配非单词开头或结尾的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了元音以外的任意字符

\S+匹配不含空白符的字符串
<a[^>]+> 匹配尖括号括住的以a开头后面不是紧跟着>的字符串**

  • 举例:<a[^>]+> 去匹配和ojvqo qwf> 的结果为和

后向引用:

子表达式的组号–(为标志(组2(组3(组4
  • 举例:\b(\w+)\b\s+\1\b
    理解:\b(\w+)\b表示一个单词
    \s+表示一个或多个空白格
    **\1\b表示选定前面的第一个括号内容为条件进行限定,限定的内容是这个单词作为末尾
:也可以自定义组号:(?<Word>\w+)把W+的组名指定成word,\k可以反向引用分组捕获的内容

举例2 **\b(\w+)\b\s+\1\b也可以写成\b(?\w+)\b\s+\k\b

总结()小括号的用法:
(aaa)匹配aaa并放入\1组中
(?aaa)匹配aaa放入name组中,或(?'name’exp)—'是单引号不是反引号
(?:aaa)匹配aaa,不捕获文本,也不分配组号
(?=aaa)匹配aaa,前面的位置
(?<=aaa)匹配aaa后面的位置
(?!aaa)匹配非aaa的位置
(?<!aaa)匹配前面不是aaa的位置
(?#comment)无效果,相当于#注释

断言—断言为真时才匹配

零宽断言:

(?=exp)也叫零宽度正预测先行断言 ,匹配以ing结尾的单词的前面部分
  • 举例:对12345-6789使用\b\w+(?=345)=12
(?<=exp)也叫零宽度正回顾后发断言,匹配以re开头的单词的后半部分
  • 举例:对12345-6789使用(?<=\b123)\w+\b=45

    **?假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890。

    (?<=\s)\d+(?=\s)表示匹配两个空白格之间的字符串 (?<=\s)表示匹配空白后面,(?=\s)表示匹配空白前面


负向零宽断言:

前面的例子出现的问题:\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词(加入q在单词最后就会报错)

解决办法:\b\w*q(?!u)\w*\b负向零宽断言
一.(?!aaa)形式,用于表示后面不再匹配的表达式aaa–>
  • 举例:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
二.(?<!exp)断言此位置的前面不能匹配表达式exp
  • 举例1:
    (?<![a-z])\d{7}匹配前面不是小写字母的七位数字

  • ***举例2:(?<=<(\w+)>).*(?=<\/\1>)

    分析:(?<=<(\w+)>)代表\w+内容的前缀; .*代表任意内容; (?=</\1>)代表/+\w+的后缀; 所以连起来就是:这里就是要匹配的内容


注释:***(?#comment)

  • 举例1:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
    分析:215(#200-249)| 255(#250-255)| 1(#0-199)
***启用“忽略模式里的空白符”选项后,
`(?<=# 断言要匹配的文本的前缀
<(\w+)>` # 查找尖括号括起来的字母或数字(即HTML/XML标签)
)# 前缀结束
*# 匹配任意文本
(?=# 断言要匹配的文本的后缀
</\1># 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
)# 后缀结束

贪婪与懒惰模式

>a.*b:效果aabab-->a.*b-->aabab贪婪模式尽量多
a.*?b:效果aabab-->a.*?b-->aabab懒惰模式尽量少
  • *? 重复任意次,但尽可能少重复
  • +? 重复1次或更多次,但尽可能少重复
  • ?? 重复0次或1次,但尽可能少重复
  • {n,m}? 重复n到m次,但尽可能少重复
  • {n,}? 重复n次以上,但尽可能少重复

处理选项

  • IgnoreCase(忽略大小写)

  • Multiline(多行模式)

  • Singleline(单行模式)

  • IgnorePatternWhitespace(忽略空白)

  • ExplicitCapture(显式捕获)

    注意:单行模式或多行模式没有任何关系,可以同时使用


递归匹配

xx <aa aa> yy中尖括号中的内容匹配出来
套路:

(?'group') 把捕获的内容命名为group,并压入堆栈(Stack)
(?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
(?(group)yes|no)如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
(?!)零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

思路:xx <aa aa> yy
<                     #最外层的左括号
[^<>]*                #最外层的左括号后面的不是括号的内容
(
    (
        (?'Open'<)    #碰到了左括号,在黑板上写一个"Open"
        [^<>]*        #匹配左括号后面的不是括号的内容
    )+
    (
        (?'-Open'>)   #碰到了右括号,擦掉一个"Open"
        [^<>]*        #匹配右括号后面不是括号的内容
    )+
)*
(?(Open)(?!))         #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败
>                        #最外层的右括号


****匹配嵌套的<div>标签:<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>.

其他:

  • \t 制表符,Tab
  • \r 回车
  • \v 竖向制表符
  • \f 换页符
  • \n 换行符
  • \A 字符串开头(类似^,但不受处理多行选项的影响)
  • \Z 字符串结尾或行尾(不受处理多行选项的影响)
  • \z 字符串结尾(类似$,但不受处理多行选项的影响)
  • (?-exp) 平衡组
  • (?im-nsx:exp) 在子表达式exp中改变处理选项
  • (?im-nsx) 为表达式后面的部分改变处理选项
  • (?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
  • (?(exp)yes) 同上,只是使用空表达式作为no
  • (?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
  • (?(name)yes) 同上,只是使用空表达式作为no

这只是我的学习笔记,原文在下面的链接,工具也是原文中的,讲解的特别好,让我终于入门了正则,在此表示感谢!

原文:http://deerchao.net/tutorials/regex/regex.htm

练习工具:http://deerchao.net/tools/regester/index.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值