2016-10-12 4 views
0

Я пытаюсь отформатировать телефонный номер в формате (###) ### - ####.iOS NSRegularExpression с условным элементом шаблона

Я использую следующее регулярное выражение с шаблоном замены

let regex = try NSRegularExpression(pattern: "([0-9]{3})([0-9]{1,3})([0-9]{0,4})") 
regex.stringByReplacingMatches(
    in: rawNumber, 
    options: .reportCompletion, 
    range: NSRange(location: 0, length: rawNumber.characters.count), 
    withTemplate: "($1) $2-$3" 
) 

Проблема заключается в том, что мой шаблон строка содержит жёстко прописанные -, который не должен появиться, если третья группа захвата $ 3 не найден.

Например:

rawNumber = "5125"

будет заменен, как (512) 5-, когда я на самом деле хочу его в формате (512) 5, потому что я не хочу - быть показано, если третья группа захвата не было найденный.

Например, я надеялся, что может быть способ сделать шаблон, как что-то вроде:

"($1) $2if$3{-}$3"

ответ

0

Вместо stringByReplacingMatches используйте matchesInString. Это даст вам список совпадений (должен быть только один), который сам содержит список диапазонов для каждой группы захвата.

Затем вы можете проверить, какая группа захвата действительно совпала, и оттуда использовать один шаблон или другой.

1

Вы можете написать свой собственный подкласс NSRegularExpression для условной замены:

class PhoneNumberConverter: NSRegularExpression { 
    override func replacementString(for result: NSTextCheckingResult, in string: String, offset: Int, template templ: String) -> String { 
     //Assuming `pattern` has always 3 captures 
     if result.rangeAt(3).length == 0 { 
      //$3 isn't found 
      return super.replacementString(for: result, in: string, offset: offset, template: "($1) $2") 
     } else { 
      return super.replacementString(for: result, in: string, offset: offset, template: "($1) $2-$3") 
     } 
    } 
} 

func convertPhoneNumber(rawNumber: String) -> String { 
    let regex = try! PhoneNumberConverter(pattern: "([0-9]{3})([0-9]{1,3})([0-9]{0,4})") 
    return regex.stringByReplacingMatches(
     in: rawNumber, 
     options: .reportCompletion, 
     range: NSRange(location: 0, length: rawNumber.characters.count), 
     withTemplate: "($1) $2-$3" 
    ) 
} 
print(convertPhoneNumber(rawNumber: "5125")) //->(512) 5 
print(convertPhoneNumber(rawNumber: "512512345")) //->(512) 512-345 
0

Не углубляясь фантазиями, я использовал подход альтернативных шаблонов в тройном условном операторе:

let rawNumber = "512512345" 

let regex = try NSRegularExpression(pattern: "([0-9]{3})([0-9]{1,3})([0-9]{0,4})") 
regex.stringByReplacingMatches(
    in: rawNumber, 
    options: .reportCompletion, 
    range: NSRange(location: 0, length: rawNumber.characters.count), 
    withTemplate: "\(rawNumber.count > 6 ? "($1) $2-$3" : "($1) $2")" 
) 

Результат для rawNumber = "5125" является "(512) 5", а rawNumber = "512512345" является "(512) 512-345".