调教正则’妹纸‘~

反正关于正则的讨论那么多了也不差我一个多分享下在Swift 4.0 中使用正则~

听人介绍

正则?WTF?

术语点,文本匹配(各语言通用)的规则工具,精准描述你对文本的需求

例子解释,比如说你给某App做登录功能,要求密码是6到18位并且只能是数字英文,那么实现这个要求的东西就是正则(当然有别的办法,本文主要说正则)

ps:例子均以Swift 4.0实现,说的简单写上去语法容易忘,贼唧(儿)难记难懂

正确的号码才能交流

假设妹纸给了电话号,我们要验证电话号正确性,确认了电话号码无误,这样你才能进行下一步

let phonePattern = "^1\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d$"
let phoneRegex: NSRegularExpression
do {try phoneRegex = NSRegularExpression(pattern: phonePattern, options: .caseInsensitive)
}
let phoneNumber = "18812345678"
let match = phoneRegex.matches(in: phoneNumber, options: [], range: NSMakeRange(0, phoneNumber.utf16.count))
let result = match.count > 0
print(result)
//输出 true
复制代码

phoneNumber是需要验证的电话号,那么phonePattern就是我们的验证电话号的正则啦,wait!phonePattern这个字符串什么鬼?这就是正则的语法,这些东西王八的屁股-规定(龟腚)~ 死记硬背没个X子用,多用自然就记住了
^带表开头
$代表结尾
\d代表任一数字
由于\d匹配任意一个数字,所以有多少\d就代表多少位数字啦、
emmmm...这样似乎有点麻烦,如果一百位岂不是要写一百个,当然还有简便写法啦,就是\d{10},其中{10}代表10位数不能多不能少。

let phonePattern = "^1\\d{10}$"
// 这样就代表匹配11位数字,开头数字为 1 剩下的 10 位数为任意数字
复制代码

诶?\d是匹配数字那\\d是什么鬼?删掉还报错!
\代表转义字符啦
转义字符是什么?就是正则里有些特殊的字符(Metacharacter)有特殊的含义

^$()*+?.[\{|
复制代码

这些特殊字符在使用前需要使用backslash \来消除歧义
wiki上如此解释道:
\将下一个字符标记为一个特殊字符(File Format Escape)、或一个原义字符(Identity Escape,有^$()*+?.[\{|共计12个)、或一个向后引用(backreferences)、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。 实在记不住也没关系,你只要知道是王八的屁股就好了,使用特殊字符必须前面多加一个\,(Swift中暂时只发现使用\需加\)那么我们就看一下常用的metacharacter

语法说明
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\n换行符
^匹配字符串的开始
$匹配字符串的结束
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

那么回到妹纸的电话号正题,电话号有些明显就是错的例如12345678888,好像还没有2开头的电话号,这样吧我们要求电话号是13,14,15,16,17,18开头的,那我们就这样

let phonePattern = "^1[345678]\\d{9}$"
复制代码

可能对于[]你产生了疑惑,这个东西就是用来自定义你想要的限制的范围啊,上面的例子就是在3,4,5,6,7,8中任意选一个,具体解释看这里

见面

正确的名字更加了解

你见到妹纸,肯定要打招呼,于是该如此

let namePattern = "^hi.*[a-z]$"
let nameRegex: NSRegularExpression
do {try nameRegex = NSRegularExpression(pattern: namePattern, options: .caseInsensitive)
}
let name = "hi! Girl"
let match = nameRegex.matches(in: name, options: [], range: NSMakeRange(0, name.utf16.count))
let result = match.count > 
print(result)
复制代码

*也是一个metacharacter,不过它代表前面的内容可以重复使用任意次,既然提到*那么我们就来看看类似*这种常用的限定符

语法说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

这样对于我们之前提到的{10}就应该很明白了。

[a-z]代表a-z的任意字母 如此看来"^hi.*[a-z]$" 的意思就很明显了,也就是说hi,任意个任意字符(except \n),1个a到z的任意字母,但实际上这样的正则有些冗余,因为.*已经代表了除换行符外的任意个任意字符,所以我们并不需要[a-z]

let namePattern = "^hi.*$"
复制代码

但是如果妹纸告诉你叫她叫123-+?这肯定是不对的,名字不能是数字和标点符号啦,肯定是字母或是中文组成的,由此看来我们的似乎应该如此效验

let namePattern = "^hi.{2}[a-z]*$"
复制代码

这样就namePattern的意思就是hi,然后除换行符外的任意两个字符,然后任意个a-z中的任意字母 为什么在.后面写{2}//重复两次呢?hi! xxx 因为打招呼写出来需要一个叹号一个空格,这样好看啊,ahhhh...

当然你也可以试试写成[a-c],这样就只会匹配abc;如果你写成数字[0-9]也是一样的效果,当然标点符号也适用[?!],这样就值匹配?!

深入了解

知道住址。。。嘿嘿嘿~

妹纸给了你地址让你去找,可是地址。。。你如何知道是否正确呢,比如第一市第一街(1101)或是第一市第一街1101。那么获取该使用如下方式来匹配这两种地址

let addressPattern = "^[\\u4e00-\\u9fa5]{5,25}(?\\d{4})?$"
let addressRegex: NSRegularExpression
do {try addressRegex = NSRegularExpression(pattern: addressPattern, options: .caseInsensitive)
}
let address = "第一街第一市(1101)"
let match = addressRegex.matches(in: address, options: [], range: NSMakeRange(0, address.utf16.count))
let result = match.count > 0
print(result)
复制代码

来看看这个"^[\\u4e00-\\u9fa5]{5,25}(?\\d{4})?$"
\u4e00-\u9fa5这是unicode中汉字的范围,显而易见它的意思是是5-25位汉字然后是能出现1次或0次中文字符的,接着四位任意数字,最后是能出现1次或0次中文字符的
看起来没什么问题,不幸的是它也可以匹配第一市第一街(1101或是第一市第一街1101)这样“不正确”的格式,为了解决这个问题我们就用到了|

let addressPattern = "^[\\u4e00-\\u9fa5]{5,25}(\\d{4})|[\\u4e00-\\u9fa5]{5,25}\\d{4}$"
复制代码

|作用是满足其中任意一种规则就匹配,满足了某个分支就不会管其他条件了,如果都不满足那么久不匹配。
也就是说其匹配规则是5-25位汉字(4位任意数字)5-25位汉字4位任意数字,这样我们就写出了我们想要的匹配效果。

完事

正则强大的地方还有很多,上面只是简单调戏了一下,如您发现调戏不当之处,您的指教是我的荣幸

如果你想详细了解,那么我推荐看这些奥~
正则表达式30分钟入门教程
8 Regular Expressions You Should Know
Wikipedia 的正则介绍
微软的正则表达
百度的正则介绍

转载于:https://juejin.im/post/5ab85de46fb9a028dd4e354f


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部