2014-09-17 20 views
9

Mam problem z uzyskaniem NSRegularExpression dopasowywania wzorców na łańcuchach z szerszymi (?) Znakami Unicode w nich. Wygląda na to, że problemem jest parametr range - Swift zlicza pojedyncze znaki Unicode, a Objective-C traktuje łańcuchy tak, jakby zawierały jednostki kodowe UTF-16.Jak używać NSRegularExpression na ciągach Swift ze znakami Unicode o zmiennej szerokości?

Oto mój ciąg testy i dwa wyrażenia regularne:

let str = "dogcow" 
let dogRegex = NSRegularExpression(pattern: "d.g", options: nil, error: nil)! 
let cowRegex = NSRegularExpression(pattern: "c.w", options: nil, error: nil)! 

mogę dopasować pierwszy regex bez żadnych problemów:

let dogMatch = dogRegex.firstMatchInString(str, options: nil, 
        range: NSRange(location: 0, length: countElements(str))) 
println(dogMatch?.range) // (0, 3) 

Ale drugi nie z tymi samymi parametrami, ponieważ zakres, który wysyłam (0 ... 7), nie jest wystarczająco długi, aby objąć cały ciąg aż do NSRegularExpression:

let cowMatch = cowRegex.firstMatchInString(str, options: nil, 
        range: NSRange(location: 0, length: countElements(str))) 
println(cowMatch.range) // nil 

Jeśli użyję inny zakres mogę uczynić sukces mecz:

let cowMatch2 = cowRegex.firstMatchInString(str, options: nil, 
        range: NSRange(location: 0, length: str.utf16Count)) 
println(cowMatch2?.range) // (7, 3) 

ale nie wiem, jak wydobyć dopasowany tekst z łańcucha, ponieważ zakres wykracza poza zakres ciąg Swift.

+1

+ jeden na odniesienie dogcow. – devios1

Odpowiedz

10

Okazało się, że można walczyć z ogniem. Korzystanie z właściwości natywnego języka Swift o nazwie utf16Count i metody substringWithRange: z - nie - uzyskuje prawidłowy wynik. Poniżej znajduje się pełny kod roboczych:

let str = "dogcow" 
let cowRegex = NSRegularExpression(pattern: "c.w", options: nil, error: nil)! 

if let cowMatch = cowRegex.firstMatchInString(str, options: nil, 
         range: NSRange(location: 0, length: str.utf16Count)) { 
    println((str as NSString).substringWithRange(cowMatch.range)) 
    // prints "cow" 
} 

(pomyślałem, to w trakcie pisania na pytanie; zdobyć jeden dla rubber duck debugging.)

+1

Jeśli najpierw konwertujesz 'let nsstr = str jako NSString', możesz po prostu użyć' length: [długość nsstr] 'jak w ObjC. –

Powiązane problemy