2010-09-22 5 views
2

J'ai besoin d'une expression régulière qui correspond A.*C seulement s'il n'y a pas de "B" entre les deux. Avant et après "A.*C sans B entre", toute chaîne est autorisée (y compris A, B et C).
"A", "B" et "C" sont des espaces réservés pour des chaînes plus longues.
Donc l'expression rationnelle devrait correspondre ie. "AfooC", "AfooCbarB", "A C B A", mais pas "AfooBbarC" ou "A B C B".Problème d'expression régulière: comment déterminer qu'il n'y a pas de B entre A et C?

Je pense que je besoin d'un .* quelque part entre A et B, alors j'ai essayé (entre autres) ces deux:
A.*(?!B).*C ne fonctionne pas, comme .* après un « mange » B.
A(?!.*B).*C n » t fonctionne, car il ne correspond pas ACB. (Cette fois, le premier .* "mange" le "C").

Peut-être qu'il me manque quelque chose d'évident - je n'arrive pas à comprendre comment le faire.

Merci pour l'aide, Julian

(Edit: ayant des problèmes de mise en forme ...)

+2

La réponse à votre question peut dépendre de la syntaxe regex utilisée. Quelqu'un a demandé la même chose pour les expressions rationnelles .NET [ici] (http://bytes.com/topic/net/answers/103977-regular-expression-match-all-except). – stakx

+0

Le problème est que A, B, C ne sont pas des caractères uniques. – jasamer

Répondre

4

La meilleure façon d'y parvenir est d'utiliser lookarounds:

A((?!B).)*C 

Ce modèle correspondra A, puis n'importe quel nombre de caractères, puis C. Cependant, en raison de l'aspect négatif sur le ., le point ne correspondra que s'il ne va pas consommer B.

+0

Génie. Merci beaucoup. – jasamer

1

Que diriez-vous de A[^B]*C? [^B] est une classe de caractères correspondant à "tout sauf la lettre 'B'".

+0

C'était aussi mon premier instinct, mais 'B' est un espace réservé pour quelque chose de plus long qu'un caractère, donc une classe de caractères ne fonctionnera pas ici. –

+0

@Daniel: Bah. Les regex de Perl 6 me manquent. – tadzik

-1

"A [^ B] * C". Correspond à un A, puis n'importe quel nombre de caractères qui n'est pas B, puis C.

+0

"B" est un espace réservé pour une chaîne plus longue. Si "B" était, disons, "XYZ", l'expression régulière serait "A [^ (XYZ)] \ * B" - mais cela ne correspondrait pas à "AXB", même si l'expression rationnelle dont j'ai besoin devrait l'être. – jasamer

0

Pourquoi pas /A(?!.*B.*(C)).*?C/?

+0

Pourquoi capturez-vous le C dans le lookahead? –

+0

De plus, le motif ne correspond pas à 'A C B C'. –

+0

Fermer ... mais il ne correspond pas à "A C B C" ...peut-être que je n'ai pas encore décrit assez précisément, qu'il peut y avoir une chaîne après le "A C" sans "B" entre les deux ... – jasamer

0

Que diriez-vous ceci:

\AA.+(?<!(.*cheesey.*))C\Z 

Le (?<!(.*cheesey.*)) a-t lookbehind négatif pour le motif .*cheesey.* et arrête correspondant si elle trouve une correspondance. Les ancres sont là pour l'empêcher de couper la fin et de faire correspondre au milieu, même si «fromage» pourrait être à la fin.

Questions connexes