调教正则’妹纸‘~
反正关于正则的讨论那么多了也不差我一个多分享下在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
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
