NSRegularExpressionenumerateMatchesInString 多次调用时挂起

作者:编程家 分类: regex 时间:2025-06-19

使用 NSRegularExpression:enumerateMatchesInString 方法多次调用时,可能会导致程序挂起。这个方法是用于在给定的字符串中搜索匹配特定正则表达式模式的子字符串,并对这些子字符串进行处理。然而,如果字符串非常大,或者正则表达式的模式非常复杂,多次调用这个方法可能会导致程序变得非常缓慢甚至挂起。

案例代码

swift

let inputString = "Hello, Swift! This is a test string. I want to find all the words that start with the letter 'S'. Let's see if NSRegularExpression can help us."

let pattern = "\\b[Ss]\\w+\\b"

let regex = try! NSRegularExpression(pattern: pattern, options: [])

regex.enumerateMatches(in: inputString, options: [], range: NSRange(inputString.startIndex..., in: inputString)) { (match, _, _) in

if let match = match, let range = Range(match.range, in: inputString) {

let word = inputString[range]

print(word)

}

}

上述代码中,我们使用了 NSRegularExpression:enumerateMatchesInString 方法来搜索 inputString 中以字母 'S' 开头的单词。正则表达式的模式为 "\\b[Ss]\\w+\\b",表示以 'S' 或 's' 开头的一个或多个字母组成的单词。我们使用了 enumerateMatches 方法来遍历所有匹配的子字符串,并将其打印出来。

当我们运行这段代码时,输出结果将是所有以 'S' 开头的单词,即 "Swift", "String" 和 "See"。

解决多次调用时挂起的问题

为了解决多次调用 NSRegularExpression:enumerateMatchesInString 方法时可能导致程序挂起的问题,我们可以将字符串的搜索和处理操作放在一个后台队列中进行,并使用回调或通知来获取结果。这样可以避免在主线程上执行耗时的操作,从而保证应用程序的响应性能。

例如,我们可以使用 GCD(Grand Central Dispatch)来在后台队列中执行搜索和处理操作,然后在主线程上更新用户界面。以下是修改后的代码:

swift

let inputString = "Hello, Swift! This is a test string. I want to find all the words that start with the letter 'S'. Let's see if NSRegularExpression can help us."

let pattern = "\\b[Ss]\\w+\\b"

let regex = try! NSRegularExpression(pattern: pattern, options: [])

DispatchQueue.global(qos: .background).async {

regex.enumerateMatches(in: inputString, options: [], range: NSRange(inputString.startIndex..., in: inputString)) { (match, _, _) in

if let match = match, let range = Range(match.range, in: inputString) {

let word = inputString[range]

print(word)

}

}

DispatchQueue.main.async {

// 更新用户界面

}

}

在上述代码中,我们使用 DispatchQueue.global(qos: .background).async 来将正则表达式的搜索和处理操作放在后台队列中执行。然后,我们可以在 DispatchQueue.main.async 中更新用户界面,以确保在主线程上执行。

使用 NSRegularExpression:enumerateMatchesInString 方法多次调用时可能导致程序挂起。为了解决这个问题,我们可以将耗时的操作放在后台队列中执行,并使用回调或通知来获取结果。这样可以保证应用程序的响应性能并避免挂起。