2010-10-27 4 views
1

Je suis en train de faire correspondre toutes les occurences de « string » dans quelque chose comme la séquence suivante sauf ceux à l'intérieur @@Comment puis-je faire correspondre des occurrences de chaîne non dans une autre chaîne en utilisant des expressions régulières?

as87dio u8u u7o @[email protected] ou os8 string os u 

-à-dire la deuxième occurrence doit être adapté, mais pas la première

Can Quelqu'un me donne une solution?

+3

@Mark Thomas: Vous devez être nouveau ici;) – webbiedave

+0

@Mark Thomas: ce n'est pas si basique, d'autant plus qu'au début regex peut être assez difficile à grok –

+0

Certes, ce n'est pas si basique, je suppose, mais ce serait quelque chose qui est documenté. Et l'OP n'a même pas essayé lui-même. Quelque chose qui le rendrait plus compliqué est s'il avait besoin de capturer seulement aux frontières de mot, par ex. s'il voulait ignorer la "chaîne" dans "astringent" –

Répondre

4

Vous pouvez utiliser negative lookahead and lookbehind:

(?<[email protected])string([email protected]) 

EDIT

NOTE: Selon les commentaires ci-dessous Marks, cela ne correspondrait pas à @string ou [email protected].

+0

ne peut pas correspondre '@ chaîne' ou' chaîne @ '(un @ d'un côté, mais pas les deux). Que cela soit souhaitable ou non, je ne suis pas sûr. – mpen

+0

@Mark Oui, mais il déclare explicitement qu'il devrait être dans @@. – steinar

+0

oui, c'est ce que je dis. '@ string' est * not * dans' @@ ', donc il * devrait * correspondre. – mpen

2

Vous pouvez essayer:

(?:[^@])string(?:[^@]) 
+0

Je crois que cela échoue s'il n'y a pas de caractères précédant ou suivant "chaîne" – mpen

+0

Ahh. Bon point. J'ai également réalisé sur mon trajet domicile-travail que cela ne correspondrait pas à @string et string @ comme mentionné dans la solution acceptée. En avant vers de meilleures compétences! – tinifni

1

OK,

Si vous voulez correspond pas à un personnage que vous le mettez dans une classe de caractères (les crochets) et commencer avec le caractère^qui nie, par exemple [^a] signifie tout caractère mais un minuscule ' une'.

Donc, si vous ne voulez pas arobase, suivi par chaîne, suivi d'un autre pas arobase, vous voulez

[^@]string[^@] 

Maintenant, le problème est que les classes de caractères verseront chacun un personnage, de sorte Dans votre exemple, nous aurions "chaîne" qui comprend les espaces de début et de fin. Donc, il y a une autre construction qui vous dit de ne rien faire correspondre, et c'est parens avec un?: Au début. (?:). Donc vous entourez les extrémités avec ça.

(?:[^@])string(?:[^@]) 

OK, mais maintenant il ne correspond pas au début de la chaîne (qui prête à confusion, est le caractère ^ faire double devoir en dehors d'une classe de caractères) ou à la fin de la chaîne $. Nous devons donc utiliser le caractère OU | pour dire "donnez-moi un début de chaîne non signé" et à la fin "donnez-moi un OU fin de chaîne" comme ceci:

(?:[^@]|^)string(?:[^@]|$) 

EDIT: L'anticipation négative vers l'avant et vers l'arrière est une solution plus simple (et intelligente), mais pas disponible pour tous les moteurs d'expressions régulières.

Maintenant, une question de suivi. Si vous aviez le mot "astringent", voulez-vous toujours faire correspondre la "chaîne" à l'intérieur? En d'autres termes, "string" doit-il être un mot par lui-même? (Malgré ma réaction initiale, cela peut devenir assez compliqué :))

Questions connexes