Swift正则匹配疑问:指定字符串为何匹配判定为true?
问题分析:为什么你的字符串会匹配正则表达式
首先,咱们直接戳破核心原因:你的字符串触发print("in"),是因为正则里的两个容易忽略的特性——.是正则通配符,以及(?i)的大小写不敏感会作用于整个正则规则。
1. 拆解你的正则表达式
先拿第一个正则(?i)No.\s?-?\s?[A-Z0-9]逐个部分拆解:
(?i):开启全局大小写不敏感模式,整个正则里的字母匹配都不区分大小写No:匹配N/n后跟O/o(因为大小写不敏感).:这是关键坑点! 它不是字面量的点号,而是正则通配符,能匹配任意单个字符(除了换行)\s?:匹配0个或1个空白字符(空格、制表符等)-?:匹配0个或1个连字符\s?:再匹配0个或1个空白字符[A-Z0-9]:因为(?i)的存在,实际会匹配任意大小写字母或数字
第二个正则(?i)N0.\s?-?\s?[A-Z0-9]逻辑类似,只是把No换成了N0(匹配N/n后跟数字0)。
2. 找到字符串里的匹配位置
你的目标字符串是:
let potential = "Kaline bypassed the Minors to join the Tigers at 18. By 20"
其中Minors这个单词里的nor子串,正好命中第一个正则的(?i)No.部分:
n匹配N(大小写不敏感)o匹配or匹配通配符.
紧接着,Minors后面的空格匹配\s?,然后to里的t(小写字母,受(?i)影响)匹配[A-Z0-9]。整个匹配的子串是nor + t,完全符合正则规则,所以matches方法返回true,触发了条件分支。
3. 如果你想匹配字面量的"No."或"N0.",该怎么修正
如果你原本想匹配的是类似No. 1、N0- A这种带字面量点号的格式,那必须把正则里的.转义成\.(因为.在正则里是通配符,要匹配真实的点号就得转义)。修正后的代码如下:
if (potential.matches("(?i)No\\.\\s?-?\\s?[A-Z0-9]") || potential.matches("(?i)N0\\.\\s?-?\\s?[A-Z0-9]")) { print("in") }
这样正则就只会匹配包含No.(或大小写变体)或N0.的子串,不会再误匹配nor这类内容了。
内容的提问来源于stack exchange,提问作者Ethan Allen
相关产品推荐
相关产品推荐

