簡體   English   中英

NSRegularExpression和重復模式

[英]NSRegularExpression and repeating pattern

我正在編寫一個通過TCP接收消息塊的應用程序。 消息塊由以下部分組成:

  • 固定的標題<<:--!!
  • 6位數字,表示信息的長度
  • 消息本身

使用NSRegularExpression從接收到的數據中提取消息聽起來很合邏輯,所以我在操場上得到了以下代碼,實現了對接收到的數據字符串的處理:

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}所以我認為您不能僅使用正則表達式就能做到這一點,因此安全的解決方案是。

  1. ^<<:--!!(\\d{6})正則表達式以提取長度N
  2. 從第13個字符開始子字符串化N個字符
  3. 重復

如果您想過着危險的生活,並且對消息中絕不會出現<<:--!!\\d{6}信心,那么此正則表達式可以解決問題。

(?<=<<:--!!\d{6})(.*?)(?=<<:--!!\d{6}|$)

只要記住, 如果分隔符出現在字符串中它將搞砸,為了安全起見,您應該在第一個示例中使用該方法。

嘗試使用模式static let messageHeaderPattern = "<<:--!!(\\\\d{6})(.+?)(?!<<:--!!)"

嘗試進一步過濾消息本身,因此(。*)中不包括第二條消息:

"(?:<<:--!!(\\d{6})([a-zA-Z ]+))"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM