我需要像JS String.prototype.split(pat: RegExp)或 Rust 的 String.splitn(pat:Pattern<'a>) 这样的功能,但是要用正则表达式实现。最终我得到了下面的代码:
extension NSRegularExpression {
convenience init(_ pattern: String) {...}
func splitn(_ str: String, _ n: Int = -1) -> [String] {
let range = NSRange(location: 0, length: str.utf8.count)
let matches = self.matches(in: str, range: range);
var result = [String]()
if (n != -1 && n < 2) || matches.isEmpty { return [str] }
if let first = matches.first?.range {
if first.location == 0 { result.append("") }
if first.location != 0 {
let _range = NSRange(location: 0, length: first.location)
result.append(String(str[Range(_range, in: str)!]))
}
}
for (cur, next) in zip(matches, matches[1...]) {
let loc = cur.range.location + cur.range.length
if n != -1 && result.count + 1 == n {
let _range = NSRange(location: loc, length: str.utf8.count - loc)
result.append(String(str[Range(_range, in: str)!]))
return result
}
let len = next.range.location - loc
let _range = NSRange(location: loc, length: len)
result.append(String(str[Range(_range, in: str)!]))
}
if let last = matches.last?.range, !(n != -1 && result.count >= n) {
let lastIndex = last.length + last.location
if lastIndex == str.utf8.count { result.append("") }
if lastIndex < str.utf8.count {
let _range = NSRange(location: lastIndex, length: str.utf8.count - lastIndex)
result.append(String(str[Range(_range, in: str)!]))
}
}
return result;
}
}
通过以下测试
func testRegexSplit() {
XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn("My . Love"), ["My", "Love"])
XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn("My . Love . "), ["My", "Love", ""])
XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn(" . My . Love"), ["", "My", "Love"])
XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn(" . My . Love . "), ["", "My", "Love", ""])
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX"), ["", "My", "", "Love", ""])
}
func testRegexSplitWithN() {
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 1), ["xXMyxXxXLovexX"])
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", -1), ["", "My", "", "Love", ""])
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 2), ["", "MyxXxXLovexX"])
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 3), ["", "My", "xXLovexX"])
XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 4), ["", "My", "", "LovexX"])
}
func testNoMatches() {
XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove", 1), ["MyLove"])
XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove"), ["MyLove"])
XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove", 3), ["MyLove"])
}
NSRegularExpression
类及其matches
函数来获取所有匹配的正则表达式呢? - rmaddy