正则匹配任意字符和空格(正则表达式的匹配规则)


正则表达式的组成元素?

我们在编码过程中无论前端或者后端或多或少会遇到正则表达式,她虽然不是必须的,但是锦上添花是一定的,所以我们有必要去掌握它的规则,读懂他,了解他的语义,直至自己按规则写出自己业务逻辑的正则表达式,比如我们在修改维护人家的代码或者赏析源代码看到类似的字符串

(<(w*)([^>]*)>)|((?<=>).*?(?=<))

如果我们不了解语义规则,是不是心里慌得一P,心里万马奔腾,啥玩意东西?我在哪里,我是谁,我不活了?

正则表达式教程 #2 如何读懂一个正则表达式?

还是有必要花点时间来学习下,如果各位同学观赏了上面的表达式产生和作者当初一样的情绪,恭喜你,两种选择,

一:自己面壁去

二:点个关注,给码字的作者一点小小的鼓励再拿个小板凳,仔细听我详细分解

言归正传,我们首先理解正则表达式的第一个基本概念:

元字符(metacharacter)

当一个字符在正则引擎中赋予特殊意义,而不再代表字符本身含义,比如.在ASCII码中为46,在正则表达式语义环境中代表除开换行结束符之外任意字符,这句话究竟什么含义也?换句话说就是比如孙大圣的七十二变,根据具体的场景,他可以变成一只小小鸟,也可以变成一个漂亮小姐姐,或者其他任何东西,从引擎解析的角度可以假装是我们要找的那个东西,到达我们想要搜索结果,和我们sql里面的%通配符一样的语义

拆分正则表达式最小元字符组

文本字符:

代表字符的本身含义,比如字符a代表ASCII 码是97,他可以匹配你搜索字符串任何位置的a字符,相当于精确匹配。

匹配单个字符元字符:

从表达式构建来说,一次匹配模式可以由一个元字符构成,也可以由多个元字符构造一组元字符完成一次匹配,那么读懂正则表达式就必须要求你有一双慧眼,可以把正则表达式拆分成一个(组)一个(组)的一次匹配模式,画重点:

  • [A-F0-9] 字符集合区间中任意一个字符都可以匹配,匹配一次消费一个搜索字符串字符
  • d 0到9任意一个数字
  • D 匹配非数字
  • [A-Za-z0-9] 匹配任意大小写字母、数字
  • w 和上面相同,匹配任意大小写字母、数字,因为正则语言规则最先是linux使用的,这种使用频率过高,语法太繁琐了,作者在引擎中又自定义了一个简单的元字符来表述该语义,如果我们自己实现的正则引擎,你可以随意发挥,用某个简单的符号(元字符)代表某一类语义.
  • 一样的道理,其他还有很多,看你用具体哪个语法那种正则引擎,大致差不多,剩下的就仅仅是使用熟悉的过程而且 So easy!

转义序列元字符 :

当我们想用元字符本身的语义去匹配我们的搜索字符串的时候,用来让正则引擎定义的元字符回归本源,比如我们想匹配IP地址:(d{1,3}.){3}d{1,3} 其中当正则引擎解析到.仅仅能匹配字符.,而不是匹配除开换行结束符之外任意字符。

位置匹配:

零宽断言)只匹配位置,不匹配字符,不consume字符,比如

  • ^ 匹配字符串的边界,行首
  • $ 匹配字符串的边界,行尾
  • b一个单词的边界
//eg:
//功能:清理空白行
final String regex = "^s*?n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
String input = "
正则表达式教程 #2 如何读懂一个正则表达式?

替换清理如图文本空行,该表达式可以拆分成三组元字符组:

  • regex[0] = ^表示断言一行的起始位置
  • regex[1] = s*? 表示匹配任意多个字符匹配空白符(等价于[rntfv ])
  • regex[2] = n 表示匹配换行符最后匹配到的结果替换为字符串空,即实现删除空白行

量词元字符:

重复匹配,定位前面(文本元字符|字符元字符|分组元字符组)匹配重复的次数

  • ? 匹配字符或者字符集合出现0次或者1次
  • * 匹配字符或者字符集合出现0次或者n次
  • + 匹配字符或者字符集合出现1次或者N次
  • {m} 匹配模式必须出现m次
  • {m,} 匹配模式最少出现m次,最多无穷N次
  • {m,n} 匹配模式最少m次,最多n次

分组捕获元字符( ):

该分组类所有元字符组匹配看着一个完整分组作为一次匹配,而且查找最近的配对闭合括弧作为一个完整的子模式,注意该分组里面也许有N多个子分组,一定要追溯到所有的子分组闭合之后,分组是正则表达式一个重要的概念,但是对于我们目前仅仅学习如何拆分一个正则表达式够了,具体子表达式具体开文详细讲。

条件选择元字符 或 |:

表示几个并行的条件,只要其中一个满足,就匹配成功

String regex1 = "(li|zh)ang";
// regex1:既能匹配liang也可以匹配zhang
String regex2 = "[li|zh]ang";
// 注意和范围单个字符匹配的不同,regex2这样写可以匹配lang iang |ang zang hang 这种组合

实战:根据上面的准备,我们来拆分开篇正则表达式: (<(w*)([^>]*)>)|((?<=>).*?(?=<))

拆分过程:

//第一次拆分:
var group1 = regex[0] = (<(w*)([^>]*)>); (这个我不认识(。•ˇ‸ˇ•。))
var group2 = regex[1] = | ;(这个我认识,分支条件嘛)
var group3 = regex[2] = ((?<=>).*?(?=<));(这个我不认识(。•ˇ‸ˇ•。))
//第二次拆分:继续拆分group1元字符组:
var group1_child_1 = group1[0] = < (这个我认识哦,原来你是匹配字符<)
var group1_child_2 = group1[1] = (w*) (原来你是配置任意大小写字母、数字,想想,哦原来作者这里是匹配html元素标签啊,比如div、img)
var group1_child_3 = group1[2] = ([^>]*)(匹配直到出现>前的任意字符)
var group1_child_4 = group1[3] = >(匹配字符>)
组合起来改组就是匹配一个html元素的开始带属性的标签,比如:<div id="header">,MD,原来如此的简单
....
继续分解,知道拆分成一个一个有意义的子模式,按规则组织匹配字符,让后我们就能读懂该正则表达式的终极奥义。

总结:

关键字:零宽断言 元字符 分组

有了这几个术语的概念,你可以把一个正则表达式庖丁解牛分成一个一个基础的元字符,弄明白他的意义,中间有不明白的元字符定义,可以查查资料,那么恭喜你,正则表达式你花5分钟就入门了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发表评论

登录后才能评论