2009-02-13 4 views

Répondre

26

Cela sonne comme un travail pour assertions arrières, mais vous devez être conscient que toutes les saveurs regex les soutenir. Dans votre exemple:

(?<=\bipsum\s)(\w+) 

Cela correspondra une séquence de lettres de caractères qui suit « lui » comme un mot entier suivi d'un espace. ne vous ne se correspond pas « très », à vous inquiéter à ce sujet réinsérant dans le cas d'exemple remplacements.

Comme 1 dit, cependant, des saveurs (JavaScript, par exemple) ne prennent pas en charge lookbehind du tout. Beaucoup d'autres (la plupart, en fait) prennent en charge que « largeur fixe » assertions arrières - donc vous pouvez utiliser cet exemple, mais aucun des opérateurs de répétition. (En d'autres termes,(?<=\b\w+\s+)(\w+)ne fonctionnerait pas.)

+0

me battre aussi :) – annakata

+0

Lookbehinds ont tendance à être assez limité quand il s'agit d'utiliser des caractères génériques cependant. – cletus

+0

Lookbehinds pourrait même ne pas être nécessaire ici. En fonction de ce que «je veux faire correspondre» dans la question, voir la solution de David Kemp. – user55400

-1

que \ b \ B

EDIT (*.): bien en fonction de votre mise en œuvre de regex, cela pourrait avoir faim et de trouver tous les mots après cette

+0

Ça va correspondre au reste de la phrase. – cletus

+0

vous devez faire cela ungreedy – tliff

+0

En fait ce n'est pas dépendant de l'implémentation, ou du moins je n'ai jamais rencontré une implémentation regex qui soit non-gourmande par défaut. Non-gourmand est toujours un switch (au moins en Perl, PHP, Java et .Net). – cletus

1

que \ b (\ w *)

+0

Cela semble correspondre seulement à ipsum. –

+0

Je ferais probablement que \ b + (\ w +) au moins – cletus

+0

ipsum \ b + (\ w +) n'est pas valide regex. –

4

Certains des autres intervenants ont suggéré d'utiliser une expression rationnelle qui ne dépend pas d'assertions arrières, mais 1 penser un exemple de travail complet, est nécessaire pour obtenir le point à travers. L'idée est que vous correspondez toute la séquence (« recherche », plus le mot suivant) de la manière habituelle, puis utiliser un groupe de capture pour isoler la partie qui vous intéresse. Par exemple,

String s = "Lorem ipsum dolor sit amet, consectetur " + 
    "adipiscing elit. Nunc eu tellus vel nunc pretium " + 
    "lacinia. Proin sed lorem. Cras sed ipsum. Nunc " + 
    "a libero quis risus sollicitudin imperdiet."; 

Pattern p = Pattern.compile("ipsum\\W+(\\w+)"); 
Matcher m = p.matcher(s); 
while (m.find()) 
{ 
    System.out.println(m.group(1)); 
} 

Notez que cette affiche à la fois « intelligent » et « maintenant ». Pour ce faire avec la version lookbehind, vous devez faire quelque chose comme hackish:

Pattern p = Pattern.compile("(?<=ipsum\\W{1,2})(\\w+)"); 

C'est Java, ce qui nécessite la lookbehind ont une longueur maximale évidente. Certaines saveurs n'ont même qu'une grande flexibilité, et bien sûr, certains ne supportent pas du tout d'assertions arrières.

Cependant, le plus grand problème des gens semblent avoir dans leurs exemples ne sont pas avec assertions arrières, mais avec des limites de mots. Les deux David Kemp et CK semblent attendre \b pour correspondre au caractère de l'espace suivant le « M », mais il n'a pas; elle correspond à la position (ou limite) entre le « m » et l'espace.

C'est une erreur commune, on 1've même vu répété dans quelques livres et des tutoriels, mais la construction de limite de mot, \b ne correspond jamais à des personnages. C'est une assertion de longueur nulle, comme lookarounds et ancres (^, $, \z, etc.), et ce qu'il correspond à une position qui est soit précédée d'un caractère de mot et non suivi d'un ou suivi d'un caractère de mot et non précédé d'un.

0

Avec javascript vous pouvez utiliser (?=ipsum.*?(\w+))

Ce obtiendra la deuxième occurrence aussi bien (Nunc)

Questions connexes