如何获取包含属于数组的单词的字符串的开头?

时间:2017-03-27 11:50:17

标签: regex swift

给出要查找的单词列表(及其复数形式):

let array = ["\\b(ab+?)(s\\b|\\b)", "\\b(cd+?)(s\\b|\\b)", "\\b(ef+?)(s\\b|\\b)", "\\b(gh+?)(s\\b|\\b)"]

这是以下内容的缩写:

let words = ["ab", "cd", "ef", "gh"]
let array = words + words.map {$0 + "s"}

我想从一个句子中得到所有的单词。从字符串的开头开始, 直到满足正则表达式的最后一个单词 。来自array或其复数形式的每个元素都应匹配(通过添加" s", ies 复数不被考虑):

例如:

let string_1 = "abc ab def cds ghi jkl bs mno" // should get "abc ab def cds"
let string_2 = "abc ghs def" // should get "abc ghs"
let string_3 = "abc ab def bc ghi" // should get "abc ab"
let string_4 = "abc def" // should get "" or nil

我目前的想法是:

let words = string_1.components(separatedBy: CharacterSet.whitespacesAndNewlines)
let lastOccurrence: (Int, String)? = words.enumerated().reversed().first(where: { (index, value) in
    if let _ = restOfSentence.range(of: value, options: .regularExpression) {
        return true
    }
    return false
})

if let l_o = lastOccurrence {
    let matchingWordsArray = words[0...l_o.0]
    let matchingWords = matchingWordsArray.joined(separator: " ")
    print(matchingWords)
}

将句子分成单词然后加入它们对我来说似乎很昂贵 有一个更好的方法吗?

1 个答案:

答案 0 :(得分:0)

你可以使用NSRegularExpression(虽然我发现它的Swift实现充满了旧的NSRange / NSString依赖):

let string_1 = "abc ab def cds ghi jkl bs mno" // should get "abc ab def cds"
let string_2 = "abc ghs def" // should get "abc ghs"
let string_3 = "abc ab def bc ghi" // should get "abc ab"
let string_4 = "abc def" // should get "" or nil


let array = ["\\b(ab+?)(s\\b|\\b)", "\\b(cd+?)(s\\b|\\b)", "\\b(ef+?)(s\\b|\\b)", "\\b(gh+?)(s\\b|\\b)"]

func matchingWords(_ string:String, patterns:[String]) -> String
{
   let anyPattern = patterns.map{"("+$0+")"}.joined(separator:"|")

   let string = NSString(string:string)
   let fullRange = NSMakeRange(0,string.length)

   if let regEx     = try? NSRegularExpression(pattern:anyPattern, options:.caseInsensitive),
      let lastRange = regEx.matches(in:string as String, range:fullRange).last?.range
   {
     return string.substring(to: lastRange.location + lastRange.length)
   }

   return ""
}

print( matchingWords( string_1, patterns:array) ) // abc ab def cds
print( matchingWords( string_2, patterns:array) ) // abc gh
print( matchingWords( string_3, patterns:array) ) // abc ab
print( matchingWords( string_4, patterns:array) ) // <empty string>