2010-11-22 4 views
2

J'essaie d'analyser une chaîne donnée pour un nombre. Le numéro ne peut pas être après "v/v./Vol/vol.", Et ne peut pas être entre parenthèses. Voici ce que j'ai:Problème Regex utilisant l'expression rationnelle ICU pour trouver des nombres qui ne sont pas entre parenthèses

NSString *regex = @"(?i)(?<!v|vol|vol\\.|v\\.)\\d{1,4}(?![\\(]{0}.*\\))"; 
NSLog(@"Result: %@", [@"test test test 4334 test test" stringByMatching:regex]); 
NSLog(@"Result: %@", [@"test test test(4334) test test" stringByMatching:regex]); 
NSLog(@"Result: %@", [@"test test test(vol.4334) test test" stringByMatching:regex]); 

Irrité, cela ne fonctionne pas. Mon regex peut être séparé en quatre parties:

(?i) - faire cas regex insensible

(?<!v|vol|vol\\.|v\\.) - regarder en arrière affirmation négative pour v/v/vol/vol..

\\d{1,4} - le nombre que je recherche, 1-4 chiffres.

(?![\\(]{0}.*\\)) - affirmation négative look-ahead: nombre ne peut pas être a) précédent, à moins qu'il ya un (avant qu'il

exaspérante, si je prends l'affirmation de regarder en arrière, cela fonctionne Quel est le problème ici..? J'utilise RegexKitLite, qui utilise la syntaxe ICU regex

Répondre

3

votre negative lookbehind est mal positionné lookbehind de ne pas modifier la position d'entrée, votre negative lookbehind devrait venir après votre expression \d{1,4}:..

(?i)\\d{1,4}(?<!v|vol|vol\\.|v\\.)(?![\\(]{0}.*\\)) 

Sinon, il suffit d'utiliser un negative lookahead pour accomplir le même but:

(?i)(?!v|vol|vol\\.|v\\.)\\d{1,4}(?![\\(]{0}.*\\)) 
+0

J'ai remarqué qu'un look-behind à largeur variable dans la classe Java 'Pattern' peut gravement affecter les performances. Cependant, je n'ai pas utilisé les bibliothèques de l'ICU, mais je ne sais pas si c'est toujours vrai. – tchrist

+0

Tout à fait raison sur le problème lookbehind - j'ai mal lu les docs. Cependant, il ne parvient toujours pas à récupérer les nombres qui ne sont pas entre parenthèses. Est-ce que ma logique n'est pas à l'intérieur des parenthèses? Exemple: @ "Chaîne de lettres 703 (1234) (plus de mots un nombre 2 ici) (plus de lettres)" –

1

Enfin fini avec cette regex:

(?i)\\d{1,4}(?<!v|vol|vol\\.|v\\.)(?![^\\(]*\\))

Le look-behind nécessaire négatif pour changer. Passes tous mes tests. Merci à Alex d'avoir mal compris le positionnement de mon NLB.

Questions connexes