前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正则表达式-基本概念与简单元字符

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

作者头像
Dylan Liu
发布2019-07-01 11:45:15
6970
发布2019-07-01 11:45:15
举报
文章被收录于专栏:dylanliudylanliu

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

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

正则表达式概念

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

wikipedia定义:

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

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

正则表达式的基本语法

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

首先要明确一点,正则引擎在匹配时是一个字符一个字符的匹配的,跟我们平常印象中一串一串匹配的思维是不同的,这个需要我们时刻牢记。

匹配单个字符的元字符

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

元字符

名称

含义

.

点号

匹配任意一个字符

[……]

字符组

匹配组内的单个字符

[^……]

排除性字符组

匹配单个未列出的字符

\meta

转义字符

特殊含义或转义元字符

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

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

关于字符组需要说明一点,可以使用-来描述一个范围,比如我们想匹配数字,我们可以写一个全列[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,},也就是没有使用占有优先量词,这个表达式是不符合要求的,大家可以试一下,然后想想,后面我们会在涉及到回溯与固化分组相关的时候就可以明白了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正则表达式概念
  • 正则表达式的基本语法
    • 匹配单个字符的元字符
      • 计数元字符
        • 简写
        • 练习
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档