精通正则表达式,看完这篇就行了
新年快乐,开工大吉
对于正则表达式,不知道你有没这种感觉,总是能按照需求写出来一些,但是不执行一下总觉得不靠谱。今天我们来简单的看看正则表单时正则表达式
一般你会用正则做什么,大部分都是做一些字符串的检查?下面有几个问题,不妨试着通过正则表达式看你是否能够解决?校验密码是否包含字母大小写、数字、特殊字符(!)且长度为6到12位将数字12345678用货币格式(每3位一个,)最终效果:12,345,678替换一段文字中的占位字符部分(比如{}包含的内容),类似ES6中的模板语法定义
正则表达式,又称规则表达式,(RegularExpression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为元字符),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑。作用
回顾下上面的3个问题,我们使用正则基本上也就是完成类似的这些工作,从功能上我们可以划分为:匹配检查目标字符串是否与指定的规则匹配。比如密码强度校验、手机号码校验、URL地址校验等等,一般用来对一段字符串进行格式校验。替换按规则对字符串内容进行替换。比如将一段文字中的特殊字符替换成空字符串,主要实现对文本按指定规则进行内容的替换截取找到字符串中特定规则的片段。可以用来提取目标字符串中满足规则的片段结构
正则表达式由普通字符以及元字符组成。其中普通字符包含09、az、AZ以及各种符号;元字符则类似?ds这种具有特殊含义的字符。字符普通字符
非打印字符
特殊字符
限定符
定位符
规则匹配贪婪匹配、惰性匹配贪婪匹配与惰性匹配影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配(惰性模式:限定符后加上?)源字符串:。。。helloRegex!。。。贪婪模式:。helloRegex!惰性模式:。?helloRegex回溯正则表达式匹配目标字符串时,它从左到右逐个测试表达式的组成部分,看是否能找到匹配项。在遇到量词时,需要决定何时尝试匹配更多字符。在遇到分支时,必须从可选项中选择一个尝试匹配。每当正则做类似的决定时,如果有必要,都会记录其他选择,以便匹配不成功时进行回溯,到最后一个决策点,再重新进行匹配。
我们可以简单的理解为,当正则匹配存在多种情况时,出现失败后的重试机制,直到所有情况都尝试失败才会最终失败。要注意有时这是非常耗费性能的正则:ab{1,3}c源字符串:abc第一次匹配:a匹配到a第二次匹配:b{1,3}匹配到b第三次匹配:b{1,3}匹配到c,因为贪婪模式,尽可能多的匹配,当匹配到b后,会继续,碰到c,匹配失败,回溯最近一次成功的状态第四次匹配:b{1,3}匹配到b第五次匹配:c匹配到c,批次成功为了减少回溯造成的性能问题,我们应该尽可能地明确需要匹配的目标字符,避免贪婪模式,比如使用b{1,3}?分组、引用和断言分组:语法()按括号从左到右,从外到内依次为分组编号使用(?组名)方式显示分配组名称断言非分组示例:(A)(B(C))则会对应多个分组:0:(A)(B(C))1:(A)2:(B(C))3:(C)引用:语法组号通过组号引用分组,减少重复引用主要是为了减少输入,但要注意正确引用Pattern。compile(()。(1))。matcher(thisiscontent)断言:(?pattern)零宽正向先行断言(前瞻)(?!pattern)零宽负向先行断言(否定前瞻)(?pattern)零宽正向后行断言(正向后视)(?第一个问题的解决方案就用到了断言只判断,不匹配模式
在javascript中,有i、g、m、s分别对应了不区分大小写、全局匹配、多行匹配以及包含换行符的元字符。匹配,而在Pattern中则提供了下面的几种模式:UNIXLINES换行符统一认定为,(window系统默认是r)CASEINSENSITIVE大小写不敏感,对应iCOMMENTS表达式中的空格及开头的注释内容被忽略MULTILINE多行模式,对应mLITERAL字面值解析模式,元字符作为普通字符处理DOTALL。可以匹配任何字符,包括行结束符,对应上面的sUNICODECASE配合CASEINSENSITIVE实现对UNICODE大小写不敏感CANONEQ启用规范等价,比如a会匹配?UNICODECHARACTERCLASS启用Unicode版本的预定义字符类和POSIX字符类,这样类似w的匹配就不局限于英文字符了元字符
所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。下面整理了元字符以及其对应的功能。
示例
下面来看下上面3个问题通过正则具体如何解决吧。。。问题1,主要使用了断言来实现,当然你也可以拆分成多个正则进行匹配来达到相同的效果TestpublicvoidcheckPassword(){Stringpasswordaaa123Z;PatterncompilePattern。compile((?。d)(?。〔az〕)(?。〔AZ〕)(?。〔!〕)〔azAZd!〕{6,12});log。info({},compile。matcher(password)。matches());}问题2,同样借助了断言,实现字符串的查找,最终实现替换,当然我们替换的不是字符,而是匹配的位置Testpublicvoidscientific(){Stringnumber123456789;Stringresultnumber。replaceAll((?B(d{3})),,);log。info({},result);}问题3,通过分组实现字符串片段的查找,通过变量上下文重新组件字符串TestpublicvoidreplaceHolder(){MapString,StringcontextnewHashMap();context。put(company,north);context。put(project,blob);context。put(model,regex);Stringpackagescom。{company}。{project}。{model}。;PatternpatternPattern。compile(({〔}〕}));Matchermatcherpattern。matcher(packages);StringBufferresultnewStringBuffer();while(matcher。find()){Stringgroupmatcher。group();Stringkeygroup。substring(1,group。length()1);matcher。appendReplacement(result,context。getOrDefault(key,));}matcher。appendTail(result);log。info(result。toString());}工具库
https:www。runoob。comregexpregexpoperator。html扩展知识
NFA引擎DFA引擎结束语
正则表达式是一种书写简单,功能强大且常用的技术,基本所有的编程语言都有其相关的实现与支持。因此深入了解正则实现原理与书写规范非常重要。
该篇主要通过简单的几个示例介绍了正则表达式的功能以及一些基本结构与功能,希望能够抛砖引玉,让你对正则表达式有更深的认识。来源;https:mp。weixin。qq。comsXuRENQXqh8EXesnDztfi3Q
作者:指北君