web-dev-qa-db-fra.com

Comment faire correspondre le premier mot après une expression avec regex?

Par exemple, dans ce texte:

Lorem ipsum dolor sit amet, consectetur elip adipiscing elit. Nunc eu tellus vel nunc pretium lacinia. Proin sed lorem. Cras sed ipsum. Nunc a libero quis risus sollicitudin imperdiet.

Je veux faire correspondre le mot après 'ipsum'.

18
Matthew Taylor

Cela ressemble à un travail de regardeurs, même si vous devez être conscient du fait que tous les types de regex ne les prennent pas en charge. Dans votre exemple:

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

Cela correspond à n'importe quelle séquence de caractères alphabétiques qui suit "ipsum" en tant que mot entier suivi d'un espace. Il ne fait pas pas correspondre à "ipsum" lui-même, vous n'avez pas à vous soucier de le réinsérer dans le cas de, par exemple. remplaçants.

Comme je l'ai dit, cependant, certaines variantes (JavaScript, par exemple) ne prennent pas du tout en charge la recherche. Beaucoup d'autres (la plupart, en fait) ne supportent que les recherches de "largeur fixe" - vous pouvez donc utiliser cet exemple, mais aucun des opérateurs de répétition. (En d'autres termes, (?<=\b\w+\s+)(\w+) non fonctionne.)

32
Ben Blank

Certains des autres répondants ont suggéré d'utiliser une expression régulière qui ne dépend pas de la recherche, mais je pense qu'un exemple complet et fonctionnel est nécessaire pour faire passer le message. L'idée est de faire correspondre la séquence entière ("ipsum" plus le prochain mot) de la manière habituelle, puis d'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 cela affiche "dolor" et "Nunc". Pour faire cela avec la version lookbehind, vous devriez faire quelque chose de bizarre comme:

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

C'est en Java, ce qui nécessite une longueur maximale évidente. Certaines saveurs n'ont même pas beaucoup de souplesse et, bien sûr, d'autres ne supportent pas du tout les regards indiscrets.

Cependant, le plus gros problème que les gens semblent avoir dans leurs exemples n’est pas le regard perdu, mais les limites de Word. David Kemp et ck semblent tous deux s'attendre à ce que \b corresponde au caractère espace suivant le 'm', mais ce n'est pas le cas; il correspond à la position (ou limite) entre le 'm' et l'espace. 

C'est une erreur courante, que j'ai déjà vue répéter dans plusieurs livres et tutoriels, mais la structure de limite de mot, \b, ne correspond jamais à aucun caractère. C'est une assertion de largeur nulle, comme des lookarounds et des ancres (^, $, \z, etc.), et sa correspondance est une position qui est soit précédée d'un caractère Word et non suivie d'un, soit suivie d'un caractère Word et pas précédé d'un.

4
Alan Moore

ipsum\b (\ w *)

1
David Kemp

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

Cela aura aussi la deuxième occurrence (Nunc)

0
JLCDev