正则表达式必知必会
正则表达式必知必会本文共有2571字,阅读耗费11分钟。本文首发于个人博客:http://tanlehua.top/posts/tech/others/learn-regex/ 什么是正则表达式一(fei)言(hua)蔽(shao)之(shuo),使用单个表达式来描述句法规则,用来匹配出符合这一句法规则的字符串。 使用场景
善假于物推荐大家使用RegexBuddy这个强大好用的神器来学习和使用正则表达式,文章底部有下载链接,有能力请支持正版。 元字符正则表达式可以理解成一门描述语言,而元字符可以理解成不可再分的关键字(key word)。 测试栗子:
下文“任意”的意思可以理解为“所有”。
说明:
那么,若用回车换行符来划分字符串的模式,要想匹配上述的测试栗子的第一行,可以用 那它们与 反义
重复模式单靠元字符来做正则表达式匹配是远远无法满足我们对海量字符串中匹配所要字符串的需求的,所以需要学习使用正则表达式的重复模式。下面的一些控制重复的字符需要跟在匹配表达式的后面。
贪婪与懒惰 Greedy&Lazy这是两个非常重要的概念。 用默认的重复模式来匹配字符串用的是贪婪模式,它会尽可能多地匹配文本。 而在上述重复符号后面加上 比如:
分支条件用 分组Why: 有时我们需要整体匹配后,在其中进行局部的字符串提取,这时就需要用到分组了。比如在一个url字符串中,我需要提取出域名。这需要先匹配出”http://”头部,接着利用分组匹配提取出域名。 How: 使用 More:
比如匹配Url的正则式:
其中 高阶玩法
场景:有时需要将分组提取出来的文本在后面重复多次匹配。如”Good,very Good”需要匹配两次Good。
断言就是判断真假,只有断言为真时,正则表达式才会往下匹配。通常来说,用一般的正则式匹配出来的文本都是要占一定宽度的。如何理解? 比如,现在有一测试文本”Script JavaScript ShellScript Javac Java”。 要匹配”JavaScript”中的”Script”,若用 怎么让”Java”不出现在匹配出的文本当中,又能表达作为匹配文本前缀的断言作用呢?零宽断言就是为此而生。 正向零宽断言:
注意,它们上面两种断言语法的细微差异,当原来的要占位断言表达式在前面,用 负向零宽断言:
实战想必大家都用过Github,Github的repository的URL是有规律的:
我们要做的很简单,就是匹配提取出userName和repoName。 测试文本:
咦,什么鬼,怎么匹配到了最后一个”/”。原来默认匹配模式是贪婪模式,需要改成懒惰模式:
发现,它懒惰过头了,竟然一个字符也不匹配。 我们来分析一下,RepoName后面如果还有内容,那必须后面紧跟着”/”,并且应该用懒惰模式。 而如果RepoName后面没有内容了,比如第三个测试文本,那就应该用贪婪模式,将剩余的全部字符作为RepoName。 因此,我们需要用分支条件: https://github.com/(.*?)/
(
(
(.*?)/.* #RepoName后面如果还有内容,那必须后面紧跟着"/",并且应该用懒惰模式
)
|
(.*) #RepoName后面没有内容了,那就应该用贪婪模式,将剩余的全部字符作为RepoName
)
因为括号嵌套过多,我们可以用 https://github.com/(?<userName>.*?)/
(?:
(?:
(?<repoName>.*?)/.*
)
|
(?<repoName>.*)
)
值得注意的是,Java对分组命名的支持不太好,分组的命名不能有重复。而且各种编程语言对正则表达式的支持可能有所差异。
https://github.com/(?<userName>.*?)/
(?:
(?<repoName>.*?
(?=/.*) # 正零宽断言
)
|
(?<repoName>.*)
)
哈哈,有种被耍的感觉,但通过这个比较简单而全面栗子,我们算是掌握正则表达式的大部分用法了。 干货正则表达式入门视频教程 RegexBuddy的安装包 ,有能力的请支持正版哈! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |