如何一次编辑大量 swift 字符串?

how can I edit lots of swift string at once?

在我的项目中,我有一个 Localizable.string 文件,它有超过 10,000 行键值格式。 我需要将所有像“contentsList.sort.viewCount”这样的 dotCase 格式的键转换为 lowerCamelCase。如何使用 swift 脚本进行转换?谢谢。

原样

"contentsList.horizontal.more" = "totall";

未来

"contentsListHorizontalMore" = "totall";

首先从字符串中获取所有行。 CompactMap 你的线将它分成两个由等号分隔的部分。获取第一个组件,否则 return nil。获取正则表达式 (\w)\.(\w) 的所有范围。用大写的第一+第二组替换匹配范围。这将删除句点。 Return 一个元素(蛇形)+ 由分隔符等号连接的其他组件的集合。现在您已经拥有了所有行,您只需要通过换行符将它们连接起来:


let string = """
"contentsList.horizontal.more" = "totall";

"whatever.vertical.less" = "summ";
"""

let pattern = #"(\w)\.(\w)"#
let lines = string.split(omittingEmptySubsequences: false,
                         whereSeparator: \.isNewline)
let result: [String] = lines.compactMap {
    let comps = [=11=].components(separatedBy: " = ")
    guard var first = comps.first else { return nil }
    let regex = try! NSRegularExpression(pattern: pattern)
    let matches = regex.matches(in: first, range: NSRange(first.startIndex..., in: first))
    let allRanges: [[Range<String.Index>]] = matches.map { match in
        (0..<match.numberOfRanges).compactMap { (index: Int) -> Range<String.Index>? in
            Range(match.range(at: index), in: first)
        }
    }
    for ranges in allRanges.reversed() {
        first.replaceSubrange(ranges[0], with: first[ranges[1]] + first[ranges[2]].uppercased())
    }
    return (CollectionOfOne(first) + comps.dropFirst())
        .joined(separator: " = ")
}
let finalString = result.joined(separator: "\n")
print(finalString)

这将打印

"contentsListHorizontalMore" = "totall";

"whateverVerticalLess" = "summ";

您可以子类化 NSRegularExpression 并覆盖 replacementString 以便能够修改由 template 参数表示的字符串。

class CapitalizeRegex: NSRegularExpression {
    override func replacementString(for result: NSTextCheckingResult, in string: String, offset: Int, template templ: String) -> String {
        guard result.numberOfRanges == 2,
              let range = Range(result.range(at: 1), in: string) else { return "" }
        return string[range].capitalized
    }
} 

然后搜索一个点后跟一个词并捕获后者。 </code> 模式会将单词 </p> 大写 <pre><code>let string = #"contentsList.horizontal.more" = "totall";"# let regex = try! CapitalizeRegex(pattern: #"\.(\b\w+\b)"#) let result = regex.stringByReplacingMatches(in: string, range: NSRange(string.startIndex..., in: string), withTemplate: "") print(result)