2017-10-21 34 views
0

斯威夫特3推出String.range(of:options)。然後,利用該功能,能夠匹配字符串的一部分而不創建NSRegularExpression對象,例如:如果不使用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),而不是隻有第一個?

+0

https://stackoverflow.com/questions/32305891/index-of-a-substring-in-a-string-with-swift/323​​06142#32306142你需要實現它自己。檢查方法範圍(的:)我如何完成這個 –

+0

@LeoDabus我正在尋找一個香草解決方案,沒有擴展或過度工程。我的情況很簡單,我會在一種情況下使用它。但是,謝謝。 – Macabeus

+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 String { 
    func ranges(of string: String, options: CompareOptions = .literal) -> [Range<Index>] { 
     var result: [Range<Index>] = [] 
     var start = startIndex 
     while let range = range(of: string, options: options, range: start..<endIndex) { 
      result.append(range) 
      start = range.lowerBound < range.upperBound ? range.upperBound : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex 
     } 
     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"] 
+0

謝謝!我真的不明白爲什麼默認庫沒有這個有用的功能。它有'range',但沒有'ranges'。 – Macabeus

+1

不客氣。至少我們可以根據需要修改語言。你可以從我發佈的鏈接添加到你的項目的範圍擴展,並根據需要使用它 –

+0

這是如何做正則表達式匹配?我不明白這是如何工作的。 – seaturtle