文章目录
前言
正则表达式是个好东西,可惜我不懂,眼瞎。于是,下决心系统的学习正则表达式,力求看懂正则表达式、会用正则表达式解决日常工作中的问题,提高工作效率。
正则表达式必知必会
入门
匹配任意字符
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 -> helloworld,helloworldjava是无法被匹配的
\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})
Java正则
java正则有一个组的概念,用()括起来,然后可以实现动态替换,比如下面2010-01-01 替换成了01 01
String s = "2010-01-01";
logger.info(s.replaceAll("2010-(\\d\\d)-(\\d\\d)", "$1 $2"))
总结
本篇博客符号较多,可能会产生一些错误,希望各位亲们多多指出!
后记
自从看了《正则表达式必知必会》这本书,发现编辑器的搜索替换功能配合正则表达式简直太强大,可以毫不夸张的说,正则表达式是所有开发人员必备的技能。
参考资料
正则表达式必知必会(修订版) [Ben Forta著]
10万+

被折叠的 条评论
为什么被折叠?



