资讯专栏INFORMATION COLUMN

正则表达式之字符匹配

GitChat / 1078人阅读

摘要:目前许多程序设计语言都支持利用正则表达式进行字符串操作。本文中的正则表达式转化为关系图来展示的工具是此文主要参考和学习了老姚的正则表达式迷你书,内容清晰明了,在此非常感谢老姚的精神,致敬。参考文献老姚著正则表达式迷你书

sharplook作为专业的日志采集分析系统,涉及的技术点,从后到前着实不少,内容也较为复杂。正则作为日志解析的手段,起着举足轻重的作用,在此小生将晦涩难懂的内容,拆解出来以便学习之用。

认识正则

维基百科对其的定义是:“正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。” 目前许多程序设计语言都支持利用正则表达式进行字符串操作。简单地理解就是,正则表达式是用于匹配字符串中字符组合的模式,要么匹配字符,要么匹配位置。

内容大纲

目前暂定以下内容将在后期分享于诸君,本篇先介绍正则表达式里面的字符匹配,实例都将以JavaScript代码演示,其实正则没有语言界限,小生也不是强权主义,只是写来方便罢了。

字符匹配

位置匹配

分组匹配

待续....

模糊匹配

正则表达式不仅可以精确匹配还可以模糊匹配,倘若只有精确匹配,那正则就太弱了,也不值得在此继续聊下去。

const reg = /hello, world/;
console.log(reg.test("hello ,world"));
// => true

而强大的模糊匹配,有两个方向上的“模糊”: 横向模糊和纵向模糊。

横向模糊

横向模糊指的是,一个正则可匹配的字符串的长度是不确定的,可以是多种情况。

其实现的方式是量词。例如{m,n},表示最少出现m次,最多出现n次。例如正则/ab{2,4}c/表示匹配一个“a”,紧接着匹配2个或者3个或者4个连续的字母“b”,最后匹配字母“c”。

可视化图如下:

测试如下:

const reg = /ab{2,4}c/g;
const string = "abc abbc abbbc abbbbc abbbbbc";
console.log(string.match(reg));
// => ["abc", "abbc", "abbbc", "abbbbc"]

正则 /ab{2,4}c/g中的‘g’是正则的修饰符,表示此正则采用全局匹配,按照顺序匹配出所有符合正则的字符串,g表示global。

纵向模糊

纵向模糊指的是,一个正则匹配的字符串,当匹配到某一位的字符时,并不是一个特定的字符,其有多种可能性。

其实现的方式是字符组。例如[abc],表示匹配的字符可能是“a”,“b”,“c”中的一个。 例如/a[123]b/表示匹配的是“a1b”,“a2b”,“a3b”其中一个。

可视化图如下:

测试如下:

const reg = /a[123]c/g;
const string = "a1c a2c a3c a4c";
console.log(string.match(reg));
// => ["a1c", "a2c", "a3c"];
字符组


字符组虽然是组的概念,但是只是表示其中一个字符。

例如[abc],表示匹配其中一个字符,它可以是“a”,“b”,“c”之一。

范围表示法

如果字符组中的字符非常多的话,怎么办呢?可以使用范围表示法。

例如“1234567abcdefgHIJKLMN”可是表示为[1-7a-gH-N]。用连字符“-”表示简写中间的项。

在这里“-”表示特殊含义,如果正则匹配需要匹配这个字符,比如匹配“a”,“h”,“-”怎么办呢? 可以写成[-ah][ah-][a-h]中的一种,这样就可以避免被作为连字符来处理了。

排除字符组

在纵向匹配中,我们还会遇到一种情况,那就是我们不希望匹配到字符组的任何一个字符。例如不能匹配“a”,“b”,“c”。

此时就出现了排除字符组的概念。例如[^abc],表示匹配除了“a”,“b”,“c”字符之外的任意一个字符。字符组中第一位放^脱字符,表示求反的概念。

当然,也有相应的范围表示法,例如:[^a-h]

常见的简写

有了字符组的概念之后,我们就很容易理解系统自带的简写方式了。

d: 表示 [0-9]。表示是一位数字。 记忆方式: 其英文是 digit(数字)。

D: 表示 [^0-9]。表示除数字外的任意一个字符。

w: 表示 [0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是 word的简写,也表示单词字符。

W: 表示 [^0-9a-zA-Z_]。表示除了数字、大小写字母和下划线之外的任意一个字符。非单词字符。

s: 表示 [ v f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式: s是 space的首字母,空白字符的单词是 white space。

S: 表示 [^ v f],表示非空白符。

. : 表示 [^ u2028u2029]。通配符,表示几乎任意字符,除了换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号 ... 中的每个点,此处省略了无数个字(什么情况都可能发生)。

如果表示任意字符,怎么办? 可以使用[dD][wW][sS][^]中任何一个。

/dDwWsS.[^]/的可视化表示如下:

量词

量词也称为重复词。理解了{m,n}后,我们再来记住一些简写方式。

简写方式

{m,}:表示至少出现m次。

{m} :表示出现m次,等价于{m,m}

? :表示出现一次或者不出现,等价于{0,1}。记忆方式: 问号的表示意思,有吗?

+ :表示出现一个或者多次,等价于{1,}。记忆方式: 加好是追加的意思,先得到一个,以后的再追加。

* :表示出现任意次数,可能不出现。记忆方式: 好比天上的星星,可能一个没有,可能只有零星几个,也可能有无数多。

贪婪匹配与惰性匹配

先看一个简单的例子:

const reg = /d{2,5}/g;
const string = "123 1234 12345 123456";
console.log(string.match(reg));
// => ["123", "1234", "12345", "12345"]

其中正则/d{2,5}/表示匹配连续的数字2次到5次。会匹配2位、3位、4位、5位连续数字。

但是其是贪婪的,它会尽可能多的匹配。你能给我 5 个,我就要 5 个。你能给我 3 个,我就要 3 个。
反正只要在能力范围内,越多越好。

但是有时候贪婪并不是一件好事(人心不足,蛇吞象)。而惰性匹配,就是尽可能少的匹配,例如下:

const reg = /d{2,5}?/g;
const string = "123 1234 12345 123456";
console.log(string.match(reg));
// => ["12", "12", "34", "12", "34", "12", "34", "56"]

其中 /d{2,5}?/ 表示,虽然 2 到 5 次都行,当 2 个就够的时候,就不再往下尝试了。

对惰性匹配的记忆方式是: 量词后面加个问号,问一问你知足了吗,你很贪婪吗?

多选分支

一个模式可以实现横向匹配和纵向匹配,而多分支可以支持多个子模式任选其一。

具体形式如下(p1|p2|p3),其中p1、p2和p3是子模式,用|(管道符)分隔,表示任选其一。

例如匹配hello或者world,正则式为/hello|world/

可视化形式如下:

测试如下:

const reg = /hello|world/g;
const string = "hello lemon, world is yours!";
console.log(string.match(reg));
// => ["hello", "world"]

需要注意的地方是,he|hello,你想匹配“hello”这个单词,结果是“he”。

如下实例:

const reg = /he|hello/g;
const string = "hello";
console.log(string.match(reg));
// => ["he"]

如果你的正则改为hello|he。匹配的结果就是“hello”

如下实例:

const reg = /hello|he/g;
const string = "hello";
console.log(string.match(reg));
// => ["hello"]

由此可知,多分支结构匹配也是惰性的,当前面匹配上之后,后面就不在匹配了。

小结

正则表达式是一个优秀程序员的基本技能,本身虽然不是很复杂,但内容却比较杂乱,能一步一步理清思路是很重要的,本章主要先介绍了字符的匹配,下一章将介绍位置的匹配。

本文中的正则表达式转化为关系图来展示的工具是Regexper

此文主要参考和学习了老姚的《JavaScript 正则表达式迷你书》,内容清晰明了,在此非常感谢老姚的 free精神,致敬。

参考文献

[1] 老姚 著《JavaScript 正则表达式迷你书》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89786.html

相关文章

  • js谜正则达式

    摘要:用正则表达式语言创建的。匹配非数字的字符使用元字符元字符在正则表达式中有特殊含义的字符。正则表达式默认是区别大小写的。正则表达式的字符串表示。若是一个正则表达式,若有标志则替换所有匹配之处,若没有则只替换第一个匹配之处。 前言 好久之前就说要写一篇正则表达式的文章,正则表达式总是记了又忘,忘了再记,记了再忘,卒。言归正传,今天终于要研究一下这个谜一样的正则表达式了。其实正则表达式并不难...

    wendux 评论0 收藏0
  • PHP基础系列正则达式(一)

    摘要:正则表达式作为一个匹配的模板,是由定界符,原子普通字符,例如有特殊功能的字符称为元字符,例如等以及模式修正符等部分组成的文字模式。正则表达式中可以使用编码。限定符限定符用来指定正则表达式的一个给定原子必须要出现多少次才能满足匹配。 正则表达式的定义 正则表达式就是描述字符排列模式的一种自定义的语法规则。由于正则表达式本身具有一套非常完整的、可以编写模式的语法体系,提供了一种灵活且直观的...

    Anchorer 评论0 收藏0
  • 正则达式初入江湖

    摘要:拿举例子只想说明你总会在一些阴暗的角落遇到正则表达式,为了到时候不至于一头雾水,我们最好简单的了解一下正则表达式的使用。 为什么要学正则表达式 很多人对正则表达式的认知只是在进行表单验证的时候在网上搜一段正则表达式进行copy,实际工作上好像很难遇到大段的正则表达式 我第一次看到大量的正则使用是在jQuery源码中,当时看的头疼只好草草的看下大概思路不了了之,但是到今天我依然不认为这种...

    caige 评论0 收藏0
  • ES6入门正则的扩展

    摘要:正则的扩展参数为字符串,那么第二个参数表示正则表达式的修饰符,如下等价于参数为一个正则表达式,这时返回一个原有正则表达式的拷贝。如下调用调用调用调用修饰符对正则表达式添加了修饰符,用来正确处理大于的字符。 showImg(https://segmentfault.com/img/bVbrJqm?w=800&h=1200); 1. 正则的扩展 参数为字符串, 那么第二个参数表示正则表达式...

    jifei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<