正则表达式怎么学必定不会

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/cblstc/article/details/100080296

前言

正则表达式是个好东西,可惜我不懂,眼瞎。于是,下决心系统的学习正则表达式,力求看懂正则表达式、会用正则表达式解决日常工作中的问题,提高工作效率。

正则表达式必知必会

入门

匹配任意字符

c.t -> cat/cut

匹配一组字符中的一个

[A-Za-z0-9] -> 字母和数字

取非操作

[^0-9] -> 非数字

匹配特殊字符

\d -> 数字
\D -> 非数字
\w -> 字母、数字和_
\s -> 空白字符(退格[\b]除外)

切换大小写

\UJava\E -> JAVA 表示全部大写
\ujava\E -> Java 表示下一个字符大写
\LJAVA\E -> java 表示全部小写
\lJAVA\E -> jAVA 表示写一个字符小写

切换大小写很实用,当我们在使用编辑器时,可以使用(查找的单词)查找单词,然后\U$1\E替换为全大写、\u$1\E替换为首字母大写等等

重复匹配

\d+ -> 1到多个数字
\d* -> 0到多个数字
\d? -> 0到1个数字
\d{3,5} -> 3到5个数字

贪婪匹配和懒惰匹配

*+都是贪婪匹配元字符,举个例子,有这么一段html代码

<h1>你好</h1>
<h1>你们好</h1>

正则表达式为<h1>.*</h1>,那么它会匹配整个字符串,跟我们的预期有出入,因为贪婪匹配会尽可能的匹配最大的字符串。
改成懒惰匹配可以很好解决这个问题,贪婪匹配元字符加上?就是懒惰匹配了,本例的正则表达式可以表示为<h1>.*?</h1>=

位置匹配

\bhelloworld\b -> helloworldhelloworldjava是无法被匹配的
\B-\B -> -的左右都是非边界字符
^Helloworld -> 以Helloworld开始,注意和取非区别,取非运算符写在[]里面
Helloworld$ -> 以Helloworld结束

分行匹配模式

如果我们需要匹配换行后的开始和结束字符串,我们可以使用分行匹配模式去改变^$的行为,使用分行匹配模式之后。^$就分别代表换行后的开始边界,换行前的结束边界。举个例子,如果我们需要匹配所有注释,那么可以使用这样的正则表达式(?m)^\s*//.*$

子表达式

为什么出现子表达式?假设我们想匹配多个Helloworld单词,使用正则表达式Helloworld*会匹配诸如Helloworlddd之类的字符串,正确的做法是用小括号将单词包裹起来(Helloworld)*

进阶

回溯引用-前后一致匹配

举个例子,HTML使用h1-h6表示标签,我们现在想匹配所有的标签,可以使用<[hH][1-6]>.*?</[hH][1-6],但是如果html表达式里面存在错误的格式,如<h1>标题</h2>,那么这种方式便行不通。需要用到回溯引用的知识点。
本例使用回溯引用的表达式为<[hH]([1-6])>.*?</[hH]\1>,其中,\1表示跟第一个子表达式的匹配一样,如果第一个子表达式匹配2,那么\1就匹配2

再举一个常用的例子:我现在使用webstorm编辑器,页面上有http://www.baidu.com的字符串,我想把它替换成<a href="http://www.baidu.com">http://www.baidu.com</a>,可以使用正则表达式(http:.*)匹配url,然后使用<a href="$1">$1</a>替换(webstorm使用$表示匹配的字符串,类似于占位符的作用)。
所以说,正则表达式用好了可以造福人类!

前后查找

向前查找

何谓向前查找,正常情况下,我们需要匹配某个字符,但又不需要在匹配结果中显示它。举个李子:匹配网址的协议,但不需要把:匹配出来,可以使用\w+(?=:)而不是\w+:,因为后者会把:匹配出来

向后查找

向前查找的对立,比如,要匹配价格的数字,不需要显示$符号,可以使用(?<=\$).*$

双剑合璧

假设我们需要获取<div>Helloworld</div>里面的内容,可以这样做(?<=<div>).*?(?=</div>)

前后查找的取非

取非的意义是:不匹配向前向后的字符,比如匹配字符串中的数字10$100 can buy 10 apples,可以这样做\b(?<!\$)\d+\b

放弃

嵌入条件(了解)

嵌入条件比较复杂,了解就好

回溯引用条件

语法:?(子表达式的位置)true_regex|false_regex
我们可能遇到这种情况,假设匹配到左括号,那么我们希望也能够把右括号匹配进去。但是如果没有左括号,我们不希望右括号被匹配到。假设我们希望匹配这两种电话号码

123-456-789
(123)456-789

可以使用(\()?\d{3}(?(1)\)|-)\d{3}-d{3}

前后查找条件

语法:?(前后查找表达式)true_regex
假设我们希望匹配第一行和第三行

11111
22222-
33333-44444

可以使用\d{5}(?(?=-)-\d{5})

总结

本篇博客符号较多,可能会产生一些错误,希望各位亲们多多指出!

后记

自从看了《正则表达式必知必会》这本书,发现编辑器的搜索替换功能配合正则表达式简直太强大,可以毫不夸张的说,正则表达式是所有开发人员必备的技能。

参考资料

正则表达式必知必会(修订版) [Ben Forta著]

猜你喜欢

转载自blog.csdn.net/cblstc/article/details/100080296
今日推荐