iOS本地化字符串:正则提取双引号包裹内容的匹配问题
Alright, let's fix that regex issue you're having with your Localizable.strings content. The problem with your original regex is that it matches any content between two double quotes—even when those quotes belong to separate wrapped sections (like the closing quote of "how" and the opening quote of "you"), which is why you're getting that unwanted ", are " result.
Let's Break Down the Solution
We need to target only content that's actually wrapped in a pair of quotes (the ones that were escaped in your Localizable.strings file). Here are two scenarios depending on how you're handling the string:
Scenario 1: Working with Parsed Localized Strings (e.g., from NSLocalizedString)
When you fetch the string via NSLocalizedString, the escaped quotes \" in your .strings file are converted to regular double quotes ". For example, you'll get a string like Hi "how", are "you".
To extract only the content inside these wrapped quotes, use a regex that matches the full "content" structure and captures the inner text, then modify your function to pull out that captured group:
func matches(for regex: String, in text: String) -> [String] { do { let regex = try NSRegularExpression(pattern: regex) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) return results.compactMap { match in // Grab the first capture group (the text inside the quotes) guard let captureRange = Range(match.range(at: 1), in: text) else { return nil } return String(text[captureRange]) } } catch let error { print("invalid regex: \(error.localizedDescription)") return [] } } // Usage example let parsedString = NSLocalizedString("title_identifier", comment: "") // Results in "Hi "how", are "you"" let extractedContent = matches(for: #"([^"]+)"#, in: parsedString) print(extractedContent) // Output: ["how", "you"]
Scenario 2: Working with Raw Localizable.strings File Text
If you're directly reading the raw text from your .strings file (where quotes are still escaped as \"), adjust the regex to target these escaped quote pairs:
// Raw line from Localizable.strings let rawLine = #"title_identifier = "Hi \"how\", are \"you\"";"# let rawExtractedContent = matches(for: #"\"([^\"]+)""#, in: rawLine) print(rawExtractedContent) // Output: ["how", "you"]
Need the Ranges Instead of Just Strings?
If you want the range positions of the extracted content (for bolding them later), modify the function to return ranges instead:
func matchRanges(for regex: String, in text: String) -> [Range<String.Index>] { do { let regex = try NSRegularExpression(pattern: regex) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) return results.compactMap { match in Range(match.range(at: 1), in: text) } } catch let error { print("invalid regex: \(error.localizedDescription)") return [] } } // Usage example let ranges = matchRanges(for: #"([^"]+)"#, in: parsedString) for range in ranges { print("Content: \(parsedString[range]), Range: \(range)") }
Why This Works
- The regex
"([^"]+)"(or\"([^\"]+)\"for raw text) specifically matches complete quote-wrapped structures. - The parentheses
()create a capture group that isolates only the text inside the quotes, ignoring any stray content between unrelated quotes.
内容的提问来源于stack exchange,提问作者devdoe

