正则表达式结尾字符重复时,为何无法获取全部预期匹配结果?
问题原因与解决方案
问题根源
你的正则表达式存在三个核心问题:
- 贪婪匹配导致范围过大:正则里的
.*是贪婪模式,会尽可能匹配最长内容——从第一个{un:开始,一直到字符串最后一个}结束,直接把两个目标片段中间的文本也包含进去,因此只返回一个大匹配结果。 - 非捕获组语法错误:你写的
(:?是错误写法,正确的非捕获组标记应为(?:,错误语法会让正则把(:?当成普通字符处理,破坏原有匹配逻辑。 - 匹配范围覆盖不全:原正则里的
[0-9]{1,9}只能匹配纯数字,无法覆盖第二个目标片段里的, Bartek部分,即便修正贪婪模式,也无法正确匹配第二个内容。
修正方案
直接使用否定字符集精准匹配目标片段,替代贪婪的.*,同时修正语法问题:
修正后的正则表达式:
"\\{un:[^}]*\\}"
[^}]*:匹配任意非}的字符,遇到第一个}就停止,完美避免跨大括号的贪婪匹配。- 整个正则会精准匹配所有以
{un:开头、以}结尾的独立片段。
完整代码示例
let input = "Hello, {un:23456} is under investigation {un:654, Bartek} along with Jason." extension String { func matchesFor(regularExpression: NSRegularExpression) -> [String] { let nsstring = self as NSString let matches = regularExpression.matches(in: self, range: NSRange(location: 0, length: nsstring.length)) return matches.map { nsstring.substring(with: $0.range) } } } // 初始化修正后的正则 guard let regex = try? NSRegularExpression(pattern: "\\{un:[^}]*\\}") else { fatalError("正则表达式无效") } // 获取匹配结果 let result = input.matchesFor(regularExpression: regex) print(result) // 输出 ["{un:23456}", "{un:654, Bartek}"]
补充说明
如果需要更严格的匹配(比如要求开头是数字,后面可选逗号加名称),可以使用更精确的正则:
"\\{un:[0-9]+(?:,\\s*\\w+)?\\}"
这个正则会匹配两种格式:
- 纯数字格式:
{un:12345} - 数字加名称格式:
{un:654, Bartek}
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

