2010-08-09 5 views
3

J'ai besoin d'une regex qui corresponde aux chaînes de lettres qui ne contiennent pas deux tirets consécutifs.Correspondance des parties de la chaîne qui ne contiennent pas de tirets consécutifs

Je suis venu près avec ce regex qui utilise lookaround (je ne vois pas d'alternative):

([-a-z](?<!--))+ 

qui donne les éléments suivants en entrée:

qsdsdqf - sqdfqsdfazer - azerzaer-azerzear

produit trois matches:

qsdsdqf-
sqdfqsdfazer-
azerzaer-azerzear

Ce que je veux est cependant:

qsdsdqf-
-sqdfqsdfazer-
-azerzaer-azerzear

Donc, mon regex perd le premier tiret, que je ne suis pas NT.

Qui peut me donner un indice ou une expression rationnelle qui peut faire cela?

+0

Quelle saveur regex utilisez-vous? (PHP, .NET, Java, etc.) –

Répondre

5

Cela devrait fonctionner:

-?([^-]-?)* 

Il veille à ce qu'il y ait au moins un caractère non-tiret entre tous les deux tirets.

+0

comme il a demandé des chaînes de lettres, vous pouvez probablement remplacer [^ -] par [a-z] (ou \ w si le trait de soulignement est autorisé, mais cela ne change pas l'idée). – kriss

+0

J'utiliserais '+' au lieu de '*'; comme c'est le cas maintenant, vous aurez toujours une correspondance supplémentaire d'une chaîne vide après la dernière "vraie" correspondance.En outre, vous faites correspondre un caractère à la fois dans un groupe de capture contrôlé par un quantificateur. c'est hideusement inefficace. Je doute que cela ait de l'importance dans ce cas, mais ce n'est pas quelque chose que vous voulez faire une habitude. Attache au moins un '+ 'sur le' [^ -] '. –

0

Me semble comme vous do voulez faire correspondre les chaînes qui contiennent des traits d'union doubles, mais vous voulez les casser dans les sous-chaînes qui ne le font pas. Avez-vous envisagé de le diviser entre des paires de traits d'union? En d'autres termes, divisés sur:

(?<=-)(?=-) 

Quant à votre regex, je pense que c'est ce que vous obtenez à:

(?:[^-]+|-(?<!--)|\G-)+ 

Le -(?<!--) correspondra un trait d'union, mais si le caractère suivant est également un trait d'union la fin se termine. La prochaine fois, \G- récupère le deuxième tiret car c'est le caractère suivant; le seul moyen qui peut arriver (sauf au début de la chaîne) est si une correspondance précédente s'est interrompue à ce point. Sachez que cette regex dépend plus de la saveur que la plupart; Je l'ai testé en Java, mais toutes les variantes ne prennent pas en charge \G et lookbehinds.

Questions connexes