如何使用C#读写iOS的Localizable_ios.strings文件并读取键值对?
嘿,这个问题我刚好折腾过!iOS的Localizable_ios.strings本质是一种有特定格式的键值对文本文件,用C#完全可以实现读写操作,甚至能轻松解析出里面的键值对。我给你拆成读取、写入两部分,附上面向实际场景的代码示例:
一、读取
.strings文件的键值对 这类文件的核心格式是每行"key" = "value";,还可能夹杂//开头的注释行和空行。读取时我们需要过滤掉无效内容,精准提取键值对:
using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; public class StringsFileHandler { public static Dictionary<string, string> ReadLocalizableStrings(string filePath) { var keyValueMap = new Dictionary<string, string>(); if (!File.Exists(filePath)) { throw new FileNotFoundException("目标.strings文件不存在,请检查路径", filePath); } // 用正则匹配标准的键值行,同时忽略注释和空行 var stringPattern = new Regex(@"^\s*""(?<key>[^""]+)""\s*=\s*""(?<value>[^""]*)""\s*;?", RegexOptions.Compiled); foreach (var rawLine in File.ReadAllLines(filePath, Encoding.Unicode)) { var trimmedLine = rawLine.Trim(); // 跳过空行和注释行 if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("//")) continue; var matchResult = stringPattern.Match(rawLine); if (matchResult.Success) { var key = matchResult.Groups["key"].Value.Trim(); var value = matchResult.Groups["value"].Value.Trim(); // 避免重复键覆盖,可根据需求调整逻辑 if (!keyValueMap.ContainsKey(key)) { keyValueMap.Add(key, value); } } } return keyValueMap; } // 调用示例 public static void Main() { var localizations = ReadLocalizableStrings(@"C:\Projects\YourApp\Localizable_ios.strings"); foreach (var pair in localizations) { Console.WriteLine($"键:{pair.Key},值:{pair.Value}"); } } }
⚠️ 注意:iOS的.strings文件默认用UTF-16 Little Endian编码(带BOM),所以读取时指定Encoding.Unicode可以避免乱码问题。
二、写入/更新
.strings文件 如果要修改现有文件,建议保留原文件的注释、空行等结构,只更新目标键值;如果是新建文件,直接按格式生成即可。
1. 更新现有文件(保留原结构)
public static void UpdateLocalizableStrings(string filePath, Dictionary<string, string> updates) { if (!File.Exists(filePath)) { throw new FileNotFoundException("目标.strings文件不存在,请检查路径", filePath); } var stringPattern = new Regex(@"^\s*""(?<key>[^""]+)""\s*=\s*""(?<value>[^""]*)""\s*;?", RegexOptions.Compiled); var originalLines = File.ReadAllLines(filePath, Encoding.Unicode); var updatedLines = new List<string>(); foreach (var line in originalLines) { var trimmedLine = line.Trim(); // 空行和注释行直接保留 if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("//")) { updatedLines.Add(line); continue; } var matchResult = stringPattern.Match(line); if (matchResult.Success) { var key = matchResult.Groups["key"].Value.Trim(); if (updates.ContainsKey(key)) { // 替换值,尽量保持原格式的空格和符号 var newLine = stringPattern.Replace(line, $"\"{key}\" = \"{updates[key]}\";"); updatedLines.Add(newLine); updates.Remove(key); // 标记为已处理 } else { updatedLines.Add(line); } } else { // 无法识别的行直接保留,避免破坏原文件 updatedLines.Add(line); } } // 把剩下未匹配的新增键值对添加到文件末尾 foreach (var newPair in updates) { updatedLines.Add($"\"{newPair.Key}\" = \"{newPair.Value}\";"); } File.WriteAllLines(filePath, updatedLines, Encoding.Unicode); } // 调用示例 public static void Main() { var changes = new Dictionary<string, string> { { "welcome", "Welcome to My Awesome App!" }, { "title_diary_2", "Travel Diary" } }; UpdateLocalizableStrings(@"C:\Projects\YourApp\Localizable_ios.strings", changes); }
2. 新建.strings文件
如果是从零创建,逻辑就简单很多:
public static void CreateLocalizableStrings(string filePath, Dictionary<string, string> keyValuePairs) { var outputLines = new List<string>(); foreach (var pair in keyValuePairs) { // 注意:如果值里有双引号,要转义成\",避免格式错误 var escapedValue = pair.Value.Replace("\"", "\\\""); outputLines.Add($"\"{pair.Key}\" = \"{escapedValue}\";"); } File.WriteAllLines(filePath, outputLines, Encoding.Unicode); }
额外注意事项
- 如果值中包含特殊字符(比如双引号、换行符),记得提前转义:双引号转成
\",换行符转成\n。 - 测试时建议先备份原文件,避免误操作导致内容丢失。
内容的提问来源于stack exchange,提问作者Srinivas M
相关产品推荐
相关产品推荐

