Swift 2 中的正则表达式 matchesInString
regex matchesInString in Swift 2
此 String 扩展中的 toCamel()
函数应该删除任何 _
后跟字符串中间的字符,并将这两个字符替换为大写。
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = advance(self.startIndex, aRange.location)
let e = advance(self.startIndex, aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.dropFirst())}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_.", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range)
let uc = s[match.range]!.uppercaseString.cdr
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
问题是 matchesInString
不会 return 那些 _
已经是上一场比赛的一部分的比赛。因此,它给出了以下结果:
try "hello_world".toCamel() //"helloWorld"
try "hello__world".toCamel() //"hello_world"
try "hello___world".toCamel() //"hello_World"
如何解决这个问题?
尝试NSRegularExpression(pattern: "_+.", options: [])
您还应该阅读 NSRegularExpression Class Reference。
+
匹配 1 次或多次。尽可能匹配多次。
将您的模式更改为 _+(.)
。这匹配一个或多个下划线后跟另一个字符。圆括号将该字符放入 捕获组 。您可以通过 rangeAtIndex
取回捕获的角色
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+(.)", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range) // the whole match range
let replaceRange = match.rangeAtIndex(1) // range of the capture group
let uc = s[replaceRange]!.uppercaseString
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
示例:
"hello_world".toCamel() // helloWorld
"hello___world".toCamel() // helloWorld
"hello_beautiful____world".toCamel() // helloBeautifulWolrd
更新 Swift 2.1.1
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = self.startIndex.advancedBy(aRange.location)
let e = self.startIndex.advancedBy(aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.dropFirst())}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+(.)", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range) // the whole match range
let replaceRange = match.rangeAtIndex(1) // range of the capture group
let uc = s[replaceRange]!.uppercaseString
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
你的代码有两个问题。
首先符合您要求的正则表达式应该是 _+[^_]{1}
.
第二个在你的 cdr
计算属性中,String(characters.dropFirst())
只排除第一个 _
字符。您可以使用 String(characters.suffix(1))
编辑代码:
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = advance(self.startIndex, aRange.location)
let e = advance(self.startIndex, aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.suffix(1))}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+[^_]{1}", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range)
let uc = s[match.range]!.uppercaseString.cdr
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
我在操场上测试了这个。
此 String 扩展中的 toCamel()
函数应该删除任何 _
后跟字符串中间的字符,并将这两个字符替换为大写。
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = advance(self.startIndex, aRange.location)
let e = advance(self.startIndex, aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.dropFirst())}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_.", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range)
let uc = s[match.range]!.uppercaseString.cdr
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
问题是 matchesInString
不会 return 那些 _
已经是上一场比赛的一部分的比赛。因此,它给出了以下结果:
try "hello_world".toCamel() //"helloWorld"
try "hello__world".toCamel() //"hello_world"
try "hello___world".toCamel() //"hello_World"
如何解决这个问题?
尝试NSRegularExpression(pattern: "_+.", options: [])
您还应该阅读 NSRegularExpression Class Reference。
+
匹配 1 次或多次。尽可能匹配多次。
将您的模式更改为 _+(.)
。这匹配一个或多个下划线后跟另一个字符。圆括号将该字符放入 捕获组 。您可以通过 rangeAtIndex
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+(.)", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range) // the whole match range
let replaceRange = match.rangeAtIndex(1) // range of the capture group
let uc = s[replaceRange]!.uppercaseString
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
示例:
"hello_world".toCamel() // helloWorld
"hello___world".toCamel() // helloWorld
"hello_beautiful____world".toCamel() // helloBeautifulWolrd
更新 Swift 2.1.1
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = self.startIndex.advancedBy(aRange.location)
let e = self.startIndex.advancedBy(aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.dropFirst())}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+(.)", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range) // the whole match range
let replaceRange = match.rangeAtIndex(1) // range of the capture group
let uc = s[replaceRange]!.uppercaseString
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
你的代码有两个问题。
首先符合您要求的正则表达式应该是 _+[^_]{1}
.
第二个在你的 cdr
计算属性中,String(characters.dropFirst())
只排除第一个 _
字符。您可以使用 String(characters.suffix(1))
编辑代码:
public extension String {
public func rangeFromNSRange(aRange: NSRange) -> Range<String.Index> {
let s = advance(self.startIndex, aRange.location)
let e = advance(self.startIndex, aRange.location + aRange.length)
return s..<e
}
public var ns : NSString {return self as NSString}
public subscript (aRange: NSRange) -> String? {
get {return self.substringWithRange(self.rangeFromNSRange(aRange))}
}
public var cdr: String {return isEmpty ? "" : String(characters.suffix(1))}
public func toCamel() throws -> String {
var s = self
let regex = try NSRegularExpression(pattern: "_+[^_]{1}", options: [])
let matches = regex.matchesInString(s, options:[], range:NSMakeRange(0, s.ns.length)).reverse()
for match in matches {
print("match = \(s[match.range]!)")
let matchRange = s.rangeFromNSRange(match.range)
let uc = s[match.range]!.uppercaseString.cdr
s.replaceRange(matchRange, with: uc)
}
if s.hasPrefix("_") {s = s.cdr}
return s
}
}
我在操场上测试了这个。