匹配正则表达式时获取单个元素

时间:2019-06-04 05:10:40

标签: ios swift regex

我给定了一个特定的字符串。

let string = "[@he man:user:123] [@super man:user:456] [@bat man:user:789]"

现在,我需要一个仅包含名称和ID的数组。为此,我应用了以下正则表达式。

extension String {
  func findMentionText2() -> [[String]] {
    let regex = try? NSRegularExpression(pattern: "(@\\w+(?: \\w+)*):user:(\\w+)", options: [])
    if let matches = regex?.matches(in: self, options:[], range:NSMakeRange(0, self.count)) {
      return matches.map { match in
            return (1..<match.numberOfRanges).map {
                let rangeBounds = match.range(at: $0)
                guard let range = Range(rangeBounds, in: self) else {
                    return ""
                }
                return String(self[range])
            }
      }
   } else {
       return []
   }
 }
}

现在,当我执行let hashString = string.findMentionText()并打印hashString时,会得到一个像这样的数组。

[["@he man", "123"], ["@super man", "456"], ["@bat man", "789"]]

到目前为止很好..:)

现在,我做了一个类型别名,并想将其添加到数组中。  所以我做到了...

 typealias UserTag = (name: String, id: String)

  var userTagList = [UserTag]()

然后

let hashString2 = string.findMentionText2()

for unit in hashString2 {
  let user: UserTag = (name: unit.first!, id: unit.last!)
  userTagList.append(user)

}

for value in userTagList {
    print(value.id)
    print(value.name)
  }

现在,这里不是要在unit.first中提供unit.lastlet user: UserTag = (name: unit.first!, id: unit.last!),而是要将nameid分别添加到类型别名中从正则表达式匹配。即当我获得名称或ID时,应将其添加到数组中,而不要使用unit.firstunit.last

我该如何实现?。

1 个答案:

答案 0 :(得分:2)

您只需要重构map即可生成UserTag数组而不是字符串数组数组。这是一种方法:

typealias UserTag = (name: String, id: String)

extension String {
    func findMentionText2() -> [UserTag] {
        let regex = try? NSRegularExpression(pattern: "(@\\w+(?: \\w+)*):user:(\\w+)", options: [])
        if let matches = regex?.matches(in: self, options:[], range:NSMakeRange(0, self.count)) {
            return matches.compactMap { match in
                if match.numberOfRanges == 3 {
                    let name = String(self[Range(match.range(at: 1), in:self)!])
                    let id = String(self[Range(match.range(at: 2), in:self)!])
                    return UserTag(name: name, id: id)
                } else {
                    return nil
                }
            }
        } else {
            return []
        }
    }
}

let string = "[@he man:user:123] [@super man:user:456] [@bat man:user:789]"
print(string.findMentionText2())

但是我建议您创建一个struct而不是使用元组。它并没有真正改变findMentionText2的实现,但是使用结构可以让您根据需要添加其他属性和方法。