“\“在字符串表示正则语义中的作用

在多数语言中,字符串中的"\"会作为转义字符串出现,用以将紧跟其后的字符转义,拓展字符的使用范围。但是在表示正则语义时,"\"会让一些使用场景显得很别扭.

别扭的"\\"

有这样一个场景:有一个文件名数组,需要从中筛选出以"json"结尾的文件名,在iOS中使用传统的正则匹配大概会这样:

Swift 复制代码
        let files = ["filea.txt", "fileb.json", "filec.json", "filed.pdf"];
        let regex = try? NSRegularExpression(pattern: ".*\\.json", options: NSRegularExpression.Options.caseInsensitive)
        let result = files.filter( { (regex?.matches(in: $0, range: NSRange(location: 0, length: $0.count)))?.isEmpty == false } )
        
        print("result:\(result)");

这时就会发现本来只是需要转义"."的"\"需要出现两次,为什么? 这里实际上经历了两个阶段的解析:

  • 所在语言的字符串解析:将"\\."解析为 \.
  • 正则引擎的正则解析: 将 \. 解析为 .

为什么必须是"\\"

在正则表达式(ERE)中, 由于"."有特殊元字符含义,所以使用其本来的意义时就需要使用"\."来表达.

而在swift中,"\"也是一个特殊含义的字符: 转义字符, 所以直接出现的"\"会被认为应该和紧跟其后的字符连起来组合称为一个新字符使用, 所以单独使用"\"会被认为是转义字符,而不是"\"本身,当需要表示"\"时就需要使用"\\"来表示一个真正意义上的"\". 所以在正则引擎中的 \. 在字符串中就会被表示成"\\.".

这里还有一个问题,在iOS的字符串中,常见的转义字符并不多:

\n \t \\ \" \r \0 \u{}

所以原则上讲,使用"\."来表示正则中的"."并没有歧义,那为什么不能直接使用"\."来表示呢?最要的原因是防止潜在的隐患.试想一下, 本来在字符串中出现"\"时,正常的逻辑是其后会出现一个需要被转义的字符,然后发现紧跟其后的是字符".", 并不是一个可以被转义的字符, 如果不报错就意味着"\anything"是一个合理的存在,在这种情况下编译器就无法进行正确的静态分析,无法提示错误,也会造成可读性下降(这他么难道是一个我不知道的转义字符). 所以, 不明语义的转义是不被允许的,这样就可以:

  • 防止拼写错误等隐藏bug;
  • 便于进行静态分析,提示错误,增强可阅读性;
  • 保持和其他主流语言(C/C++/Python/JavaScript/Java等)的逻辑一致性

其他实现方式

事实上,在swift中并不是必须使用这种看起来别扭的语法,有很多方式可以避开这种逻辑.

原始字符串

可以使用原始字符串来避开转义逻辑,上边的实现就可以使用

Swift 复制代码
        let regex = try? NSRegularExpression(pattern: #".*\.json"#, options: NSRegularExpression.Options.caseInsensitive)

来进行替换,这样就可以避开所在语言字符串的转义解析.

使用新的API

在Regex中已经直接使用"/pattern/" 来表示匹配模式,上边的实现可以修改为:

Swift 复制代码
 let result = files.filter({ $0.wholeMatch(of: /.*\.json/) != nil })

其他非正则的方式

可以借助于其他非正则封装的方式来实现,比如 `hasSuffix`之类.

相关推荐
东坡肘子1 小时前
越来越慢的 App Review,拦住了谁? -- 肘子的 Swift 周报 #149
人工智能·swiftui·swift
冯汉栩18 小时前
Swift Control View,Label渐变颜色(源码)
开发语言·ios·swift
大熊猫侯佩5 天前
Xcode 预览新升级:arguments 让界面调试井井有条
swiftui·xcode·swift
大熊猫侯佩6 天前
WWDC26:把 SwiftUI Toolbar 真正握在手心里
swiftui·swift·apple
大熊猫侯佩6 天前
WWDC 26 全新 ResultsObserver:终于能在 View 外面盯着 SwiftData 了
swiftui·swift·apple
大熊猫侯佩6 天前
别再把大模型供在云端了,WWDC26 CoreAI 大模型下凡实战
ai编程·swift·wwdc
00后程序员张6 天前
有没有更轻量的 iOS 开发环境?快蝎kxapp轻量化路径与构成
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
sakiko_7 天前
Swift学习笔记39-实战注意事项
前端·笔记·学习·swift
东坡肘子7 天前
Apple Intelligence 已通过审核,即将在中国提供服务 -- 肘子的 Swift 周报 #148
人工智能·swiftui·swift
初级代码游戏9 天前
iOS开发 Swift 速记7:结构体和类
开发语言·ios·swift