使用正则表达式在字符串中查找多个引用的单词

Find multiple quoted words in a string with regex

我的应用程序支持 5 种语言。我有一个字符串,其中有一些双引号。此字符串在 localizable.strings 个文件中被翻译成 5 种语言。

示例:

title_identifier = "Hi \"how\", are \"you\"";

我想通过查找这些词的范围来加粗此字符串中的 "how" 和 "you"。所以我试图从字符串中提取这些引用的单词,结果将是一个包含 "how" 和 "you" 或其范围的数组。

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.map {
            String(text[Range([=11=].range, in: text)!])
        }
    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return []
    }
}

matches(for: "(?<=\")[^\"]*(?=\")", in: str)

结果是:["how", ", are ", "you"] 而不是 ["how","you"]。我认为此正则表达式需要添加一些内容,以允许它在找到两个引号后搜索下一个引号,从而避免引号之间的单词。

您的问题在于使用不使用文本但检查其模式是否匹配的环视,并且 return truefalse。见your regex in action, are 匹配,因为上一个匹配的最后一个"没有被消耗,正则表达式索引保持在w之后,所以下一个匹配可以以[开始=13=]。您需要在这里使用 consuming 模式,"([^"]*)".

但是,您的代码只会 return 完全匹配。您可以在此处使用 .map {[=18=].trimmingCharacters(in: ["\""])} trim 第一个和最后一个 ",因为正则表达式仅匹配开头和结尾的一个引号:

matches(for: "\"[^\"]*\"", in: str).map {[=10=].trimmingCharacters(in: ["\""])}

这里是 regex demo.

或者,通过在 [=20=].range 之后附加 (at: 1) 来访问第 1 组值:

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.map {
            String(text[Range([=11=].range(at: 1), in: text)!])
        }
    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return []
    }
}

let str = "Hi \"how\", are \"you\""
print(matches(for: "\"([^\"]*)\"", in: str))
// => ["how", "you"]