You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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: "&quot;", 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 &quot;name&quot; 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: "&quot;", 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:00:12