Получить отдельные элементы при сопоставлении с регулярным выражением - PullRequest
0 голосов
/ 04 июня 2019

У меня есть определенная строка, заданная примерно так ...

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

Теперь мне нужен массив, содержащий только имя и идентификатор. Для этого я применил следующее регулярное выражение ..

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 и хочу добавить его в массив .. И я сделал это ...

 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.last в let user: UserTag = (name: unit.first!, id: unit.last!), вы хотите добавить name и id к typealias, как и когда они сопоставляются с регулярным выражением .. т.е. когда я получить имя или идентификатор, его нужно добавить в массив вместо того, чтобы давать unit.first или unit.last ..

Как мне этого добиться? ..

1 Ответ

2 голосов
/ 04 июня 2019

Вам просто нужно провести рефакторинг вашего 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, но использование структуры позволяет добавлять другие свойства и методы по мере необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...