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

Swift字符串解析器分号处理问题:User Defaults编辑App开发困境

处理User Defaults字符串解析的分号与字典识别问题

我正在开发一款允许用户编辑User Defaults的App,以此免费屏蔽烦人的更新提示,但遇到了技术问题。我的代码本应接收字符串并输出指定格式,但在处理分号时存在缺陷,运行代码可发现列表中的分号解析异常。

指定输出格式要求:

  • 单个值输出格式:myValue --> fsfsfsf
  • 列表输出格式:
    LIST myList
    -- value1234=gdwhgdqghdq
    -- anotherone=1334
    

初始代码

let lookup = """
{
    AppleAccentColor = "-2";
    "Build History" =     {
        71031 = "2024-05-20 15:50:24 +0000";
    };
    "Editor Focus Mode" = 1;
    "Editor Focus Scope" = Text;
    "Editor Last Used Syntax Control" = 31;
    "Editor Syntax Control" = 31;
    "External Files Bookmarks" = {length = 219, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000a4 };
    "External Files Manual Order" =     (
    );
    "External Files Options" = 0;
    "Favorites Bookmarks" = {length = 219, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000a4 };
    "Favorites Manual Order" =     (
    );
    "Favorites Options" = 0;
    "First Launched Version" = "7.1.3";
    "Last Launched Build" = 71031;
    "Last Launched Version" = "7.1.3";
    "Library Locations Bookmarks" = {length = 219, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000a4 };
    "Library Locations Include Dropbox" = 0;
    "Library Locations Include Google Drive" = 0;
    "Library Locations Manual Order" =     (
    );
    "Library Locations Options" = 1;
    "Library Navigation History Items" = {length = 586, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000001d4 };
    "Library Window Frame" = "{{498, 253}, {1230, 833}}";
    "Library Window State" = {length = 569, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000001b7 };
    NSCloseAlwaysConfirmsChanges = 0;
    NSCloseAlwaysConfirmsChangesCustomized = 1;
    NSQuitAlwaysKeepsWindows = 1;
    NSQuitAlwaysKeepsWindowsCustomized = 1;
    "NSSplitView Subview Frames Library Split View" =     (
        "0.000000, 0.000000, 118.000000, 833.000000, NO, NO",
        "119.000000, 0.000000, 230.000000, 833.000000, NO, NO"
    );
    "NSSplitView Subview Frames Split View" =     (
        "0.000000, 0.000000, 349.000000, 833.000000, NO, NO",
        "350.000000, 0.000000, 880.000000, 833.000000, NO, NO"
    );
    "Ping Installation Identifier" = "2B8719BA-0BB5-41BF-A616-C02B2BFA23BF-4407-0000005617A366C4";
    "Preview PDF Scale Configuration" = {length = 359, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 00000111 };
    "Stats Counter Values" = {length = 263, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000ca };
    "Version History" =     {
        "0.0" = "2024-05-20 15:50:24 +0000";
    };
}
"""

// 移除首尾的大括号
var mutable = lookup
mutable.removeLast()
mutable.removeFirst()

// 移除所有换行和空格
mutable = mutable.replacingOccurrences(of: "\n", with: "")
mutable = mutable.replacingOccurrences(of: " ", with: "")

// 移除最后的分号
mutable.removeLast()

// 按分号分割成片段
var segments = mutable.components(separatedBy: ";")

print(segments)

func parseKeyValue(from input: String) -> (key: String, value: String)? {
    guard let range = input.range(of: "=") else {
        return nil
    }
    let key = String(input[..<range.lowerBound]).trimmingCharacters(in: .whitespacesAndNewlines)
    let value = String(input[range.upperBound...]).trimmingCharacters(in: .whitespacesAndNewlines)
    return (key: key, value: value)
}

// 输出片段内容
for segment in segments {
    print("-----")
    if let keyvalues = parseKeyValue(from: segment) {
        
        // 判断是列表/字典还是单个值
        
        if (keyvalues.value.hasPrefix("(") && keyvalues.value.hasSuffix(")")) || (keyvalues.value.hasPrefix("{") && keyvalues.value.hasSuffix("}")) || (keyvalues.value.hasPrefix("[") && keyvalues.value.hasSuffix("]")) {
            print("LIST: \(keyvalues.key)")
            var listContent = keyvalues.value
            listContent.removeFirst()
            listContent.removeLast()
            let values = listContent.split(separator: ",")
            for value in values {
                print("-- \(value)")
            }
        } else {
            print(keyvalues.key + "  -->  " + keyvalues.value)
        }
    } else {
        print("格式无效!")
    }
}

更新说明

感谢Rob的帮助,我完成了一个可运行的简易脚本,但该脚本无法识别字典类型:

import Foundation

let lookup = """
{
    "AppleAccentColor": "-2",
    "Build History": {
        "71031": "2024-05-20 15:50:24 +0000"
    },
    "Editor Focus Mode": 1,
    "Editor Focus Scope": "Text",
    ...
}
"""

guard let data = lookup.data(using: .utf8) else {
    fatalError("字符串转Data失败")
}

do {
    if let dictionary = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
        for (key, value) in dictionary {
            print("-----")
            print("\(key) --> \(value)")
        }
    } else {
        print("JSON反序列化为字典失败")
    }
} catch {
    print("JSON反序列化错误: \(error)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:33:12