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

Swift多行字符串拆分及Kanna中匹配元素索引获取问题求助

我来帮你一步步解决这两个Swift问题~

问题1:拆分包含可选变量的多行字符串字面量

这里的核心是先安全解包可选变量,再对字符串进行拆分操作——强制解包!很容易导致崩溃,推荐用if let或guard let做安全处理,再搭配Swift原生的字符串拆分API:

示例代码:处理可选的多行字符串

假设你有一个可能为nil的多行字符串:

let optionalMultiLineText: String? = """
Kazuo®/Ishiguro® Auprès® (2 pack)
Orange
Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)
Blue
"""

// 安全解包后拆分,过滤空行
if let text = optionalMultiLineText {
    let lines = text.components(separatedBy: .newlines).filter { !$0.isEmpty }
    print(lines)
    // 输出: ["Kazuo®/Ishiguro® Auprès® (2 pack)", "Orange", "Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)", "Blue"]
}

如果是多行字符串字面量中嵌入可选变量,需要先给可选值一个默认值再拼接:

let optionalBrand: String? = "Kazuo®/Ishiguro®"
let multiLineString = """
\(optionalBrand ?? "默认品牌") Auprès® (2 pack)
Orange
\(optionalBrand ?? "默认品牌") Auprès® Folio Toujours (2 Pack)
Blue
"""

let lines = multiLineString.components(separatedBy: .newlines).filter { !$0.isEmpty }

问题2:处理Kanna查询结果的文本拆分与索引查找

从你的描述来看,你踩了API过时的坑,还有对字符串/数组索引方法的误解,我们逐个解决:

一、修复文本拆分失败的问题

你尝试的三种方法失效,主要是因为API过时或者文本中的分隔符不是标准换行符(比如你给出的典型输出看起来更像空格分隔,而非换行)。推荐用Swift原生的split方法,兼容各种场景:

推荐代码:安全处理Kanna节点并拆分文本

// 先安全处理Kanna的查询结果,避免强制解包崩溃
guard let doc = doc, let productLinks = doc.css("a[class^='product-link']") else {
    print("没有找到匹配的产品链接节点")
    return
}

for node in productLinks {
    guard let rawText = node.text else { continue }
    
    // 方案1:按所有换行符拆分(兼容\n、\r、\r\n)
    let linesByNewline = rawText.split(whereSeparator: \.isNewline)
        .map(String.init)
        .filter { !$0.isEmpty }
    
    // 方案2:如果文本实际是用空白字符分隔(比如你给出的典型输出)
    let linesByWhitespace = rawText.split(whereSeparator: \.isWhitespace)
        .map(String.init)
        .filter { !$0.isEmpty }
    
    print("按换行拆分结果:\(linesByNewline)")
    print("按空白拆分结果:\(linesByWhitespace)")
}

为什么你之前的方法报错?

  • componentsSeparatedByCharactersInSet:这是Objective-C时代的旧API,Swift 3+已经废弃,改用components(separatedBy: CharacterSet),比如:
    let lineArray = multiLineString.components(separatedBy: .newlines).filter{! $0.isEmpty}
    
  • split方法的错误:你用了NSCharacterSet.newlineCharacterSet(),Swift中应该用CharacterSet.newlines,而且characterIsMember的类型处理很麻烦,不如直接用split(whereSeparator: \.isNewline)更简洁。
  • enumerateLines返回function():这应该是调试时的误解——enumerateLines的闭包参数line就是每行的字符串,只要你正确append(line),lineArray肯定是[String]类型,不会是function。可能是你没有正确打印数组,或者node.text本身为空?

二、修复元素索引查找的问题

你用index(of:)报错,是因为字符串的index(of:)方法是用来查找单个Character的,而你传入的是String。正确的做法是先把拆分后的文本放到数组里,再用数组的firstIndex(of:)方法:

示例代码:查找数组元素的索引

// 假设已经得到拆分后的产品文本数组
let productLines = ["Kazuo®/Ishiguro® Auprès® (2 pack)", "Orange", "Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)", "Blue"]

// 精确匹配查找索引
if let orangeIndex = productLines.firstIndex(of: "Orange") {
    print("Orange的索引是:\(orangeIndex)") // 输出: Orange的索引是:1
}

// 模糊匹配(包含指定字符串)查找索引
if let folioIndex = productLines.firstIndex(where: { $0.contains("Folio Toujours") }) {
    print("Folio Toujours的索引是:\(folioIndex)") // 输出: Folio Toujours的索引是:2
}

内容的提问来源于stack exchange,提问作者solo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:55:01