我正在编写一个通过 TCP 接收消息 block 的应用程序。消息 block 由以下部分组成:
- 固定 header
<<:--!!
- 给出消息长度的 6 位数字
- 消息本身
使用 NSRegularExpression 从接收到的数据中提取消息听起来合乎逻辑,所以我最终在 playground 中使用以下代码,实现了对接收到的一串数据的处理:
import UIKit
struct Constants {
static let messageHeaderPattern = "<<:--!!(\\d{6})(.+)"
}
let receivedData = "<<:--!!000010My message"
let regex = try! NSRegularExpression(pattern: Constants.messageHeaderPattern, options: []) // Define the regular expression
let range = NSMakeRange(0, receivedData.characters.count) // Define the range (all the string)
let matches = regex.matchesInString(receivedData, options: [], range: range) // Get the matches
print("Number of matches: \(matches.count)")
for match in matches {
let locationOfMessageLength = match.rangeAtIndex(1).location
let expectedLengthOfMessage = Int(receivedData.substringWithRange(Range(start: receivedData.startIndex.advancedBy(locationOfMessageLength),
end: receivedData.startIndex.advancedBy(locationOfMessageLength + 6))))
let locationOfMessage = match.rangeAtIndex(2).location
let lengthOfMessage = match.rangeAtIndex(2).length
let data = receivedData.substringWithRange(Range(start: receivedData.startIndex.advancedBy(locationOfMessage),
end: receivedData.startIndex.advancedBy(locationOfMessage + lengthOfMessage)))
// data contains "My message"
}
此代码运行良好,但前提是字符串中只有一条消息。为了使其适用于多条消息,我更改了正则表达式:
static let messageHeaderPattern = "(?:<<:--!!(\\d{6})(.+))+"
和接收到的数据:
let receivedData = "<<:--!!000010My message<<:--!!000014Second message"
但仍然只有一个匹配项,数据包含My message<<:--!!000014Second message
.
我的正则表达式有什么问题?
最佳答案
该消息甚至可以包含 <<:--!!\d{6}
所以我不认为你可以单独使用正则表达式来做到这一点,所以安全的解决方案是。
^<<:--!!(\d{6})
的正则表达式提取长度N- 从第13个开始串出N个字符
- 重复
如果你想过危险的生活并且有信心<<:--!!\d{6}
永远不会出现在消息中,那么这个正则表达式就可以解决问题。
(?<=<<:--!!\d{6})(.*?)(?=<<:--!!\d{6}|$)
请记住,如果分隔符出现在字符串内部,会造成困惑,为了安全起见,您应该使用我第一个示例中的方法。
关于ios - NSRegularExpression 和重复模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34884581/