在不使用NSRegularExpression的情况下,如何获取字符串正则表达式的所有匹配项?

时间:2017-10-21 05:13:32

标签: regex swift nsregularexpression

Swift 3介绍了String.range(of:options)。然后,使用此函数,可以匹配字符串的一部分而不创建NSRegularExpression对象,例如:

let text = "it is need #match my both #hashtag!"
let match = text.range(of: "(?:^#|\\s#)[\\p{L}0-9_]*", options: .regularExpression)!

print(text[match]) //  #math

但是,是否可以匹配正则表达式的两次出现(即#match#hashtag),而不仅仅是第一次?

1 个答案:

答案 0 :(得分:1)

let text = "it is need #match my both #hashtag!"
// create an object to store the ranges found
var ranges: [Range<String.Index>] = []
// create an object to store your search position
var start = text.startIndex
// create a while loop to find your regex ranges
while let range = text.range(of: "(?:^#|\\s#)[\\p{L}0-9_]*", options: .regularExpression, range: start..<text.endIndex) {
    // append your range found
    ranges.append(range)
    // and change the startIndex of your string search
    start = range.lowerBound < range.upperBound ? range.upperBound : text.index(range.lowerBound, offsetBy: 1, limitedBy: text.endIndex) ?? text.endIndex
}
ranges.forEach({print(text[$0])})

这将打印

#match

#hashtag

如果您需要在代码中多次使用它,则应将此扩展名添加到项目中:

extension StringProtocol {
    func ranges(of string: Self, options: String.CompareOptions = []) -> [Range<Index>] {
        var result: [Range<Index>] = []
        var start = startIndex
        while start < endIndex,
            let range = self[start..<endIndex].range(of: string, options: options) {
            result.append(range)
            start = range.lowerBound < range.upperBound ?
                    range.upperBound : index(after: range.lowerBound)
        }
        return result
    }
}

用法:

let text = "it is need #match my both #hashtag!"
let pattern = "(?:^#|\\s#)[\\p{L}0-9_]*"
let ranges = text.ranges(of: pattern, options: .regularExpression)
let matches = ranges.map{text[$0]}
print(matches)  // [" #match", " #hashtag"]