正则表达式-基本概念与简单元字符

正则表达式工做中一直在使用,可是没有系统的总结过,今天就从小白的角度梳理一下正则表达式的使用,主要关注的是正则的思想java

边写边听五月天的派对动物。学会了正则省下的时间就能够去party了 ^_^node

正则表达式概念

咱们先来看看正则表达式的概念,毕竟正则的语法、使用都是围绕着它要解决的问题来的。正则表达式

wikipedia定义:编程

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),
又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法,
是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
在不少文本编辑器里,正则表达式一般被用来检索、替换那些匹配某个模式的文本。

首先,正则表达式是一个字符串组成的模式,用来匹配一个字符串,通常用在检索,替换里,也常常用来校验一些字符模式,检验是否匹配一个给定的规则。编程语言

正则表达式的基本语法

正则表达式使用字符串来描述字符串,也就是说跟编程语言,正则表达式是有本身的关键字的,学会这些关键字是咱们入门正则的第一步,而后在使用中领会正则表达式的思想,一步步进阶。编辑器

首先要明确一点,正则引擎在匹配时是一个字符一个字符的匹配的,跟咱们日常印象中一串一串匹配的思惟是不一样的,这个须要咱们时刻牢记。工具

匹配单个字符的元字符

咱们首先来看一下匹配一个字符的关键字:日志

元字符 名称 含义
. 点号 匹配任意一个字符
[……] 字符组 匹配组内的单个字符
[^……] 排除性字符组 匹配单个未列出的字符
\meta 转义字符 特殊含义或转义元字符

英文点号能够匹配任意字符,可是不包括换行符,也就是说匹配到换行点号就匹配失败了,咱们可使用\n来匹配换行符,在java中也有MULTI_LINES来指定让点号匹配到换行符code

若是咱们想匹配一个文本形式的点号怎么弄呢,可使用反斜线\来转义关键字,这样就能够匹配一个点号,而不是匹配任意字符的关键字点号了。regexp

关于字符组须要说明一点,可使用-来描述一个范围,好比咱们想匹配数字,咱们能够写一个全列[0123456789],也可使用[0-9],字符也是同样[a-zA-z]匹配英文大小写的26个字母,若是咱们想匹配横杠怎么办呢?只有一个办法,那就是把它写在紧跟左中括号后面,[-a-z]匹配横杠和a-z的全部字母,若是写在中间是会被当成关键字来解析的。

计数元字符

有了匹配单个字符的关键字,匹配多个就要用到计数元字符,经常使用的有下面这些:

元字符 名称 含义 区间表示
? 问号 匹配至多一次 {0,1} greedy的
* 星号 匹配任意屡次,也能够不匹配 {0,}
+ 加号 匹配至少一次 {1,}
{min, max} 区间 min <=匹配次数 <= max grep默认不支持{元字符,可使用-E选项
*?,+?,??,{min,max}? 忽略优先量词 匹配尽量少的内容
*+, ++, ?+ {min,max}+ 占有优先量词 匹配内容后不会交还,相似固化分组

?*+这三个元字符是可使用{}来模拟的,不过在一些正则流派里不支持{}元字符,咱们只能使用这三个。

在为加?的量词上,前四个都是贪婪匹配的,也就是说他们会匹配尽量多的字符,在匹配失败的时候才会中止,这有时候颇有用,但有时候会让咱们没有通过深思写出来的正则匹配到错误的内容。第四列在量词后面加了?则正相反,它会匹配尽量少的内容,是先为人后为几的,这两种方式的区别咱们后面再讲,这跟表达式引擎的递归与回溯有关。

最后一列是占有优先量词,这个概念是在贪婪的基础上加了铁公鸡属性(占有),也就是说经它匹配过的字符就是它的了,不会再吐出来。后面咱们在讲回溯跟固化分组时是再来回顾这个占有优先量词。

简写

上面二者组合能够匹配大部分字符了,不过有些写起来很繁琐,所以正则为咱们提早定义好了一些简写,使用时能够减小表达式长度。

元字符 名称 含义
\s [ \f\v\t\n\r] 匹配空格,制表符,回车、换行
\S 除\s以外的任何字符
\w [a-zA-Z0-9_] 匹配一个单词
\W [^a-zA-Z0-9] 匹配除\w外的任何字符
\d [0-9] 数字
\D [^0-9] 非数字

注:相同字母的小写跟大写在这是互补的,也就是互为补集,不过须要注意一点,在这里面没有包含Unicode字符,不一样的正则引擎对这些有不一样的实现,譬如\d有的正则引擎能够匹配Unicode中的数字,也就是说中文也是有可能匹配的,这个能够参考各自的语言工具书(不过通常这样用没啥问题)。

练习

我这里使用nodepad++来练习正则表达式,Linux下有些字符处理起来比较麻烦,Java写起来又太啰嗦,怎么简便怎么来。

找出一段文字中的数字

\d+[0-9]+

这里使用加号是由于数字至少出现一次才是合法的,若是使用*则能够匹配任意位置,由于*能够不匹配任何字符

日志里常根据关键字和id来定位,通常如何使用呢?

假设关键字为keyword, id为13235413,而且id在后面,咱们可使用keyword.*13235413来匹配含有这个模式的一行日志,这里加不加问号对咱们没有影响

找出一行里含有至少10个单词的行,假设单词以空格分割


线


不存在惟一的答案,我是这样写的(\w++ *){10,},第一次写成了(\w+ *){10,},也就是没有使用占有优先量词,这个表达式是不符合要求的,你们能够试一下,而后想一想,后面咱们会在涉及到回溯与固化分组相关的时候就能够明白了。

相关文章
相关标签/搜索