首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Objective-C 實現 UBB 標籤解析與動態替換實戰

     編輯:關於C

業務場景

顯示「某用戶做了某事」,用戶名可修改,歷史文案需同步更新。服務端下發 UBB 標籤格式:[UserId]uid[/UserId],客戶端解析替換為當前暱稱。

正則表達式演進過程

// v1: 僅匹配內容,遺漏方括號
NSString *reStr = [NSString stringWithFormat:@"[%@].*[/%@]", tag, tag];

// v2: 嘗試轉義,但 .* 貪婪匹配
reStr = [NSString stringWithFormat:@"\[%@\].*[/%@\]", tag, tag];

// v3: 雙重轉義修正
reStr = [NSString stringWithFormat:@"\\[%@\\].*\\[/%@\\]", tag, tag];

// v4: 惰性匹配修正貪婪(多標籤場景)
reStr = [NSString stringWithFormat:@"\\[%@\\].*?\\[/%@\\]", tag, tag];

分類擴展:NSMutableString+UBBParser

@interface NSMutableString (UBBParser)
- (void)enumUBBTag:(NSString *)tag
       usingBlock:(void (^)(NSRange tagRange, NSString *content,
                            NSMutableString *currentStr, BOOL *stop))block;
@end

實現要點

  • 使用 NSRegularExpression 迭代匹配
  • 回調提供 tagRange(整個標籤範圍)、content(uid 內容)、currentStr(可直接修改)、stop(提前終止)
  • 參考 NSArray enumerateObjectsUsingBlock: 設計風格

使用範例

[displayString enumUBBTag:@"UserId" usingBlock:^(NSRange range, NSString *uid,
                                                  NSMutableString *str, BOOL *stop) {
    NSString *currentName = [UserManager currentDisplayNameForUID:uid];
    if (currentName.length == 0) currentName = uid;  // 兜底顯示 uid
    [str replaceCharactersInRange:range withString:currentName];
}];

工程考量

  • 效能: 正則對長文本可能較慢,高頻調用可改用有限狀態機(FSM)單遍掃描解析。
  • 巢狀標籤: 正則難以處理巢狀,FSM 或遞迴下降解析器更適合。
  • 安全性: 替換內容需防注入(如標籤內包含 [/UserId]),解析器應嚴格匹配最內層。
  • 快取: 正則物件 NSRegularExpression 應快取重用,避免重複編譯。
  • 測試案例: 空標籤、重疊標籤、惡意輸入、超長 uid、Unicode 字元等。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved