2016-10-28 1 views
2

ich versuchte hello_world-helloWorld dieses Code-Snippet (Swift 3.0) zu ändern: wurdeWie ersetzt man einen String mit seinem Großbuchstaben mit NSRegularExpression in Swift?

import Foundation 

let oldLine = "hello_world" 
let fullRange = NSRange(location: 0, length: oldLine.characters.count) 
let newLine = NSMutableString(string: oldLine) 

let regex = try! NSRegularExpression(pattern: "(_)(\\w)", options: []) 
regex.replaceMatches(in: newLine, options: [], range: fullRange, 
    withTemplate: "\\L$2") 

Das Ergebnis newLine = "helloLworld"

I "\\L$2" als Vorlage verwendet, weil ich diese Antwort sah: https://stackoverflow.com/a/20742304/5282792 sagen \L$2 ist das Muster für das Großbuchstabe der zweiten Gruppe in der Ersatzvorlage. Aber es funktionierte nicht in NSRegularExpression.

So kann ich eine Zeichenfolge mit seinem Großbuchstaben mit einem Ersatzschablonenmuster in NSRegularExpression ersetzen.

+0

SublimeText verwendet Boost-Regex, das den '\ L'-Operator unterstützt. Swift verwendet ICU, es unterstützt keine Case-Chahing-Operatoren. –

+0

@ WiktorStribiżew So 'NSRegularExpression' unterstützt nichts anderes als' $ num' in der Ersatzvorlage? –

+0

Ein Backslash ist auch ein spezielles Zeichen in ICU-Regex-Ersatzmustern, siehe [* ICU-Benutzerhandbuch: Ersatztext *] (http://www.icu-project.org/userguide/regexp). –

Antwort

1

Eine Möglichkeit, mit zu arbeiten, Ihr Fall ist Unterklasse NSRegularExpression und überschreiben replacementString(for:in:offset:template:) Methode.

class ToUpperRegex: NSRegularExpression { 
    override func replacementString(for result: NSTextCheckingResult, in string: String, offset: Int, template templ: String) -> String { 
     guard result.numberOfRanges > 2 else { 
      return "" 
     } 
     let matchingString = (string as NSString).substring(with: result.rangeAt(2)) as String 
     return matchingString.uppercased() 
    } 
} 

let oldLine = "hello_world" 
let fullRange = NSRange(0..<oldLine.utf16.count) //<- 
let tuRegex = try! ToUpperRegex(pattern: "(_)(\\w)") 
let newLine = tuRegex.stringByReplacingMatches(in: oldLine, range: fullRange, withTemplate: "") 
print(newLine) //->helloWorld 
0

Das beantwortet nicht die Frage regex gehören, aber vielleicht nicht unbedingt für die Leser von Interesse sein, um Regex zu verwenden, um diese Aufgabe auszuführen (besser gesagt, mit nativen Swift)

extension String { 
    func camelCased(givenSeparators separators: [Character]) -> String { 
     let charChunks = characters.split { separators.contains($0) } 
     guard let firstChunk = charChunks.first else { return self } 
     return String(firstChunk).lowercased() + charChunks.dropFirst() 
      .map { String($0).onlyFirstCharacterUppercased }.joined() 
    } 

    // helper (uppercase first char, lowercase rest) 
    var onlyFirstCharacterUppercased: String { 
     let chars = characters 
     guard let firstChar = chars.first else { return self } 
     return String(firstChar).uppercased() + String(chars.dropFirst()).lowercased() 
    } 
} 

/* Example usage */ 
let oldLine1 = "hello_world" 
let oldLine2 = "fOo_baR BAX BaZ_fOX" 

print(oldLine1.camelCased(givenSeparators: ["_"]))  // helloWorld 
print(oldLine2.camelCased(givenSeparators: ["_", " "])) // fooBarBazBazFox 
Verwandte Themen