2016-10-12 1 views
0

J'essaye de formater un numéro de téléphone au format (###) ### - ####.iOS NSRegularExpression avec pièce conditionnelle de modèle

J'utilise l'expression rationnelle suivante avec le modèle de remplacement

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" 
) 

Le problème est que ma chaîne de modèle inclut le - hardcoded qui ne devrait pas apparaître si le troisième groupe de capture $ 3 est introuvable.

Par exemple:

rawNumber = "5125"

serait remplacé comme (512) 5- quand je veux réellement dans le format (512) 5, parce que je ne veux pas le - à afficher à moins que le troisième groupe de capture était a trouvé.

Par exemple, j'espérais qu'il pourrait y avoir un moyen de faire un modèle comme quelque chose comme:

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

Répondre

0

Au lieu de stringByReplacingMatches, utilisez matchesInString. Cela vous donnera la liste des correspondances (il devrait y en avoir une seule), qui contient elle-même la liste des plages pour chaque groupe de capture.

Vous pouvez ensuite vérifier quel groupe de capture correspond réellement et, à partir de là, utiliser un modèle ou l'autre.

1

Vous pouvez écrire votre propre sous-classe de NSRegularExpression pour le remplacement conditionnel:

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

Sans obtenir de fantaisie, je l'approche des modèles alternatifs dans un opérateur conditionnel ternaire:

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")" 
) 

Résultat rawNumber = "5125" est tandis que rawNumber = "512512345" est "(512) 512-345".