2010-12-15 55 views
2

J'ai une expression régulière qui ressemble à ceci:Regexp écraser sur iPhone

^(\+\d\d)?(?(?<=\+\d\d)((|)\(0\)(|)| |)|(0))(8|\d\d\d?)[-/ ]?\d\d(?\d){1,4} ?\d\d$ 

Il est utilisé pour valider les numéros de téléphone suédois. Dans d'autres environnements, tels que .NET, cette expression régulière fonctionne correctement, mais dans Objective-c, elle provoque un blocage, indiquant que l'expression régulière n'est pas une expression rationnelle valide. Je suis loin d'être un expert en matière d'expressions régulières, donc je me demande si quelqu'un peut peut-être m'aider à trouver la raison pour laquelle cette expression ne fonctionne pas.

J'utilise Reggy pour valider l'expression rationnelle et le problème semble être ce groupe

(?(?<=\+\d\d)((|)\(0\)(|)| |)|(0)) 

mais je ne peux pas comprendre pourquoi ... Si je retire (? et ) dès le début et à la fin de ce groupe, l'accident disparaît. Est-ce que quelqu'un sait ce que fait (?? Pour autant que je sais ? est utilisé pour spécifier qu'un groupe est facultatif, mais qu'est-ce que cela signifie quand il est utilisé au tout début d'un groupe?

Répondre

2

sa condition:

 
(?(condition)true-expression|false-expression) 

et parce que NSPredicate utilise package regexp de soins intensifs, de telles conditions ne sont pas disponibles. Voir:

http://userguide.icu-project.org/strings/regexp

Vous devez utiliser une bibliothèque regex tiers.

-Marc

1

J'ai fait votre regex « lisible » en le transformant en forme verbeux et annotant, afin que vous puissiez voir ce qu'il essaie de faire. J'espère que vous serez d'accord que la plupart de ce ne fait pas beaucoup de sens:

^     # Start of string 
(\+\d\d)?   # Match + and two digits optionally, capture in backref 1 
(?(?<=\+\d\d)  # Conditional: If it was possible to match +nn previously, 
(\s?\(0\)\s?|\s|) # then try to match (0), optionally surrounded by spaces 
        # or just a space, or nothing; capture that in backref 2 
|     # If it was not possible to match +nn, 
(0)    # then match 0 (capture in backref 3) 
)     # End of conditional 
(8|\d\d\d?)   # Match 8 or any two-three digit combination --> backref 4 
[-/\s]?    # match a -,/or space optionally 
\d\d    # Match 2 digits, don't capture them 
(\s?\d){1,4}  # Match 1 digit, optionally preceded by spaces; 
        # do this 1 to 4 times, and capture only the last match --> backref 5 
\s?\d\d    # Match an optional space and two digits, don't capture them 
$     # End of string 

Dans sa forme actuelle, il valide les chaînes comme

+46 (0) 1234567 
+49 (0) 1234567 
+00 1234567 
+99 08 11 1 11 

012-34 5 6 7 8 90 

et il échoue sur des chaînes comme

+7 123 1234567 
+346 (77) 123 4567 
+46 (0) 12/34 56 7 

Donc, je doute vraiment qu'il fasse ce qu'il devrait. En dehors de cela, la plupart des expressions rationnelles peuvent être beaucoup simplifiées, en supprimant le conditionnel qui déclenche votre bibliothèque regex sur le chemin. Cela n'a pas beaucoup de sens d'optimiser quelque chose qui est cassé, mais si votre client insiste, voici une version qui a exactement la même fonctionnalité, mais sans conditions:

^(?:\+\d\d(?: ?(?:\(0\)\s?)?)?|0)(?:8|\d\d\d?)[-/ ]?\d\d(?: ?\d){1,4} ?\d\d$ 
+0

Merci! Je n'ai pas créé le Regexp moi-même, donc je ne suis pas sûr des règles et des formats de numéros de téléphone autorisés. Il provient d'une autre application (web) que mon client utilise et souhaite maintenant implémenter la même validation dans une application iPhone. – andlin

+0

C'est un peu ce à quoi je m'attendais. Éditera ma réponse. Bien que vous devriez certainement dire à votre client que vous remplacez quelque chose cassé par quelque chose d'aussi cassé :) –