2010-07-19 6 views
0

J'ai une chaîne qui ressemble à:Comment choisir une correspondance d'expression régulière sur un index arbitraire?

ABC-DEF01-GHI54677-JKL 9988-MNOP

Entre chaque - peut être pratiquement tout caractère répété un certain nombre de fois.

J'utilise cette expression régulière:

[^-]* 

Comment puis-je faire 'match' du match au 2ème indice (par exemple DEF01)? Ou le 3ème (GHI54677) ou le 4ème (JKL! 9988)?

Le moteur que j'utilise ne me permet pas de spécifier un index de correspondance ou un code supplémentaire - tout doit être fait dans l'expression.

Répondre

2

La deuxième série de parens capture "DEF", "GHI" et "JKL", respectivement ...

([^-]+-){1}([^-]+) 
([^-]+-){2}([^-]+) 
([^-]+-){3}([^-]+) 

Si cela est perl, faire le premier ensemble de parens non-capture, à savoir:

# perl -de 0 
$_="ABC-DEF-GHI-JKL-MNO" 
p /(?:[^-]+-){1}([^-]+)/ 
    DEF 
p /(?:[^-]+-){2}([^-]+)/ 
    GHI 
p /(?:[^-]+-){3}([^-]+)/ 
    JKL 

$_="ABC-DEF01-GHI54677-JKL!9988-MNOP" 
p /(?:[^-]+-){1}([^-]+)/ 
    DEF01 
p /(?:[^-]+-){2}([^-]+)/ 
    GHI54677 
p /(?:[^-]+-){3}([^-]+)/ 
    JKL!9988 

Explication:

(?: = non-capturing parens 
[^-] = a non-dash character 
+ = one or more 
- = a dash 
) = close paren 
{3} = repeat 3 times 

Cette partie "gobe" 1, 2, 3, ou tout autre numéro que vous voulez, des blocs, Leavin g le prochain ensemble à prendre celui que vous recherchez.

Au lieu de +, vous pouvez également utiliser {1,} ce qui signifie 1-à-tout-nombre.

Si vos blocs peuvent être de taille zéro,:

ABC - GHI-JKL

Et vous voulez trouver le deuxième, qui est "" (chaîne vide), puis utilisez * au lieu de +. Ou vous pouvez utiliser {0,}, ce qui signifie 0-à-tout-nombre.

+0

Cette réponse à ma question, mais je compris que je l'avais écrit incorrectement. Mes excuses, cela a été clarifié. –

+0

pas de problème, il suffit de changer '{3}' à '+' ou '{1,}' si vous voulez dire 1-ou-plus-non-dash-choses, ou '*' ou '{0,}' si vous signifie zéro ou plus – eruciform

+0

réponse mise à jour ... – eruciform

1

Vous n'avez pas spécifié le moteur de langue/expression régulière que vous utilisez, mais certains (la plupart?) Vous permettent d'appliquer une correspondance répétée à la même chaîne de façon itérative. Par exemple, pcrecpp vous permet de faire:

pcrecpp::StringPiece piece("ABC-DEF-GHI-JKL-MNO"); 
pcrecpp::RE re("([^-]+)-?"); 
unsigned int index = 3; // e.g., for GHI 

std::string group; 
for(unsigned int i = 0; i < index; i++) 
    re.Consume(&piece, &group); 

// group now contains "GHI". Calling Consume again would give it JKL 
+0

Merci, malheureusement, je ne peux pas utiliser de code supplémentaire - tout doit être fait dans l'expression. J'ai maintenant clarifié la question. –

0

Différentes réponses basées sur votre révision: Voulez-vous simplement cela?

(?:[^-]+-){index-1}([^-]+) 

Le groupe non-capture correspond index-1 des sous-blocs, donc pour index=3 il correspond ABC-DEF01-, puis le groupe de capture correspond GHI54677

Questions connexes