iOS中如何获取两已知子串间的子串?及XML错误信息提取问询
嘿,我来帮你搞定这两个iOS开发里的问题!
iOS开发:获取两个已知子串之间的子字符串
不管你用Swift还是Objective-C,都可以通过定位子串位置再截取的方式实现,我给你分别写了带错误处理的示例代码,避免找不到子串时崩溃:
Swift 实现
核心思路是先找到起始子串的结束位置,再从这个位置开始搜索结束子串的起始位置,最后截取中间内容:
func substring(between startSubstring: String, and endSubstring: String, in originalString: String) -> String? { // 定位起始子串的范围 guard let startRange = originalString.range(of: startSubstring) else { print("找不到起始子串 \(startSubstring)") return nil } // 起始截取位置是起始子串的末尾 let startPosition = startRange.upperBound // 从起始位置开始搜索结束子串 guard let endRange = originalString.range(of: endSubstring, range: startPosition..<originalString.endIndex) else { print("找不到结束子串 \(endSubstring)") return nil } // 截取并返回目标字符串 return String(originalString[startPosition..<endRange.lowerBound]) } // 测试调用 let testString = "用户ID[START]12345[END],用户名:张三" if let result = substring(between: "[START]", and: "[END]", in: testString) { print(result) // 输出:12345 }
Objective-C 实现
逻辑和Swift一致,用OC的字符串方法处理:
- (NSString *)substringBetweenStart:(NSString *)startStr end:(NSString *)endStr inOriginal:(NSString *)originalStr { NSRange startRange = [originalStr rangeOfString:startStr]; if (startRange.location == NSNotFound) { NSLog(@"未找到起始子串:%@", startStr); return nil; } // 计算起始截取位置 NSInteger startPos = startRange.location + startRange.length; // 从起始位置开始搜索结束子串 NSRange endRange = [originalStr rangeOfString:endStr options:0 range:NSMakeRange(startPos, originalStr.length - startPos)]; if (endRange.location == NSNotFound) { NSLog(@"未找到结束子串:%@", endStr); return nil; } // 截取目标范围的字符串 NSRange targetRange = NSMakeRange(startPos, endRange.location - startPos); return [originalStr substringWithRange:targetRange]; } // 测试调用 NSString *testStr = @"用户ID[START]12345[END],用户名:张三"; NSString *result = [self substringBetweenStart:@"[START]" end:@"[END]" inOriginal:testStr]; NSLog(@"%@", result); // 输出:12345
从XML错误片段提取关键SQL错误信息
你给出的错误片段里,关键内容是SQL状态码、错误描述和失败行详情,用正则表达式能精准定位,我也准备了简单的备选方案:
Swift 正则提取示例
这个方法会直接把三个关键部分提取出来,方便快速定位问题:
func extractSQLErrorDetails(from errorXML: String) -> (stateCode: String?, errorMsg: String?, detail: String?) { // 正则匹配规则:匹配SQLSTATE、错误信息和DETAIL部分 let regexPattern = #"SQLSTATE\[([^\]]+)\]:.*?ERROR: (.*?)<br /> DETAIL: (.*?)\."# guard let regex = try? NSRegularExpression(pattern: regexPattern, options: .dotMatchesLineSeparators) else { return (nil, nil, nil) } let fullRange = NSRange(errorXML.startIndex..., in: errorXML) // 查找第一个匹配项 if let match = regex.firstMatch(in: errorXML, options: [], range: fullRange) { // 提取分组内容并还原转义的双引号 let stateCode = String(errorXML[Range(match.range(at: 1), in: errorXML)!]) let errorMsg = String(errorXML[Range(match.range(at: 2), in: errorXML)!]).replacingOccurrences(of: """, with: "\"") let detail = String(errorXML[Range(match.range(at: 3), in: errorXML)!]) return (stateCode, errorMsg, detail) } return (nil, nil, nil) } // 测试调用 let errorXML = #"<p class="break-long-words trace-message">SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "name" violates not-null constraint<br /> DETAIL: Failing row contains (165, null, null, 11, null, 2018-04-19 03:01:48, null, f, 6).</p>"# let errorInfo = extractSQLErrorDetails(from: errorXML) print("SQL状态码:\(errorInfo.stateCode ?? "未找到")") print("错误信息:\(errorInfo.errorMsg ?? "未找到")") print("失败行详情:\(errorInfo.detail ?? "未找到")")
输出结果:
SQL状态码:23502 错误信息:null value in column "name" violates not-null constraint 失败行详情:Failing row contains (165, null, null, 11, null, 2018-04-19 03:01:48, null, f, 6)
备选方案:先清理HTML再提取
如果正则对你来说有点复杂,也可以先清理HTML标签和转义字符,再提取错误部分:
func cleanAndGetSQLError(from errorXML: String) -> String? { // 移除所有HTML标签 var cleanedStr = errorXML.replacingOccurrences(of: #"<[^>]+>"#, with: "", options: .regularExpression) // 还原转义的双引号 cleanedStr = cleanedStr.replacingOccurrences(of: """, with: "\"") // 从SQLSTATE开始提取完整错误信息 if let sqlStartIndex = cleanedStr.range(of: "SQLSTATE")?.lowerBound { return String(cleanedStr[sqlStartIndex...]) } return nil }
调用后会得到清晰的错误文本:SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "name" violates not-null constraint DETAIL: Failing row contains (165, null, null, 11, null, 2018-04-19 03:01:48, null, f, 6).
内容的提问来源于stack exchange,提问作者Chen Li Yong
相关产品推荐
相关产品推荐

