Swift 不依赖空格从含单双字符符号的源字符串提取匹配符号数组的实现
问题根因
之前基于CharacterSet实现的方案存在本质缺陷:CharacterSet只能识别单个字符的集合,天生不支持多字符符号的匹配。比如==是由两个字符组成的完整匹配单元,原有实现会将其拆分为两个独立的=字符分别识别,最终得到["+", "+", "=", "="]的错误结果,和需求不符。
核心实现逻辑
- 预处理待匹配符号:将符号数组按字符串长度从长到短排序,扫描时优先匹配更长的符号,避免短符号抢先占用字符,导致长符号无法完整匹配
- 逐位扫描源字符串:从字符串起始位置开始逐位遍历,遇到匹配成功的符号就存入结果数组,直接将扫描指针移动到匹配符号的末尾位置,跳过已处理字符,避免重复匹配
- 全程不依赖空格做切分,即使源字符串没有任何分隔空格也能正常识别
可运行Swift代码
func extractSymbols(from source: String, matching symbols: [String]) -> [String] { // 按符号长度倒序排列,优先匹配多字符组合 let sortedSymbols = symbols.sorted { $0.count > $1.count } var result = [String]() var currentIndex = source.startIndex while currentIndex < source.endIndex { var isMatched = false // 从当前位置开始尝试匹配所有候选符号 for symbol in sortedSymbols { // 计算当前位置开始、对应符号长度的子串边界,越界则跳过 guard let subStringEnd = source.index( currentIndex, offsetBy: symbol.count, limitedBy: source.endIndex ) else { continue } let compareTarget = source[currentIndex..<subStringEnd] if compareTarget == symbol { result.append(symbol) currentIndex = subStringEnd isMatched = true break } } // 未匹配到符号则指针前移1位,继续扫描下一个位置 if !isMatched { currentIndex = source.index(after: currentIndex) } } return result }
示例测试
let source = "a + b + 3 == c" let symbols = ["+", "-", "==", "!"] let operations = extractSymbols(from: source, matching: symbols) print(operations) // 输出结果:["+", "+", "=="],和预期完全一致
补充说明
- 方案完全不依赖字符串中的空格切分,即使将源字符串改为无空格的
"a+b+3==c",也能得到相同的正确匹配结果 - 排序优先匹配长符号的逻辑,解决了符号集同时存在单字符、双字符相似符号时的歧义问题,比如符号集同时包含
=和==时,不会将连续两个=拆分为两个单字符匹配
内容的提问来源于stack exchange,提问作者Smally
相关产品推荐
相关产品推荐

