正则表达式是个好东西,可惜我不懂,眼瞎。于是,下决心系统的学习正则表达式,力求看懂正则表达式、会用正则表达式解决日常工作中的问题,提高工作效率。
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代码
你好
你们好
正则表达式为
,那么它会匹配整个字符串,跟我们的预期有出入,因为贪婪匹配会尽可能的匹配最大的字符串。.*
改成懒惰匹配可以很好解决这个问题,贪婪匹配元字符加上?
就是懒惰匹配了,本例的正则表达式可以表示为
=.*?
\bhelloworld\b
-> helloworld
,helloworldjava
是无法被匹配的
\B-\B
-> -的左右都是非边界字符
^Helloworld
-> 以Helloworld
开始,注意和取非区别,取非运算符写在[]
里面
Helloworld$
-> 以Helloworld
结束
如果我们需要匹配换行后的开始和结束字符串,我们可以使用分行匹配模式去改变^
和$
的行为,使用分行匹配模式之后。^
和$
就分别代表换行后的开始边界,换行前的结束边界。举个例子,如果我们需要匹配所有注释,那么可以使用这样的正则表达式(?m)^\s*//.*$
为什么出现子表达式?假设我们想匹配多个Helloworld
单词,使用正则表达式Helloworld*
会匹配诸如Helloworlddd
之类的字符串,正确的做法是用小括号将单词包裹起来(Helloworld)*
举个例子,HTML使用h1-h6表示标签,我们现在想匹配所有的标签,可以使用<[hH][1-6]>.*?[hH][1-6]
,但是如果html表达式里面存在错误的格式,如
,那么这种方式便行不通。需要用到回溯引用的知识点。标题
本例使用回溯引用的表达式为<[hH]([1-6])>.*?[hH]\1>
,其中,\1
表示跟第一个子表达式的匹配一样,如果第一个子表达式匹配2,那么\1
就匹配2
再举一个常用的例子:我现在使用webstorm编辑器,页面上有http://www.baidu.com
的字符串,我想把它替换成http://www.baidu.com
,可以使用正则表达式(http:.*)
匹配url,然后使用$1
替换(webstorm使用$表示匹配的字符串,类似于占位符的作用)。
所以说,正则表达式用好了可以造福人类!
何谓向前查找,正常情况下,我们需要匹配某个字符,但又不需要在匹配结果中显示它。举个李子:匹配网址的协议,但不需要把:
匹配出来,可以使用\w+(?=:)
而不是\w+:
,因为后者会把:
匹配出来
向前查找的对立,比如,要匹配价格的数字,不需要显示$
符号,可以使用(?<=\$).*$
。
假设我们需要获取
里面的内容,可以这样做(?<=
取非的意义是:不匹配向前向后的字符,比如匹配字符串中的数字10$100 can buy 10 apples
,可以这样做\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著]