172 votes

JavaScript : lookbehind négatif équivalent ?

Est-il un moyen de réaliser l'équivalent d'un négatif lookbehind en javascript les expressions régulières? J'ai besoin de correspondre à une chaîne qui ne commence pas par un ensemble de caractères.

Il semble que je suis incapable de trouver une regex qui fait cela sans faute si le contenu de la partie au début de la chaîne. Négatif lookbehinds semble être la seule réponse, javascript, mais n'en a pas.

EDIT: C'est la regex que je voudrais travailler, mais il n'a pas:

(?<!([abcdefg]))m

Donc, il correspond au 'm' dans 'jim' ou 'm', mais pas 'jam'

0 votes

C

1 votes

T E

0 votes

@ F .

109voto

JBE Points 998

Comme Javascript prend en charge la recherche avancée, un moyen sûr de le faire est :

Je dire vous voulez faire une postanalyse comme ceci

  1. Inverser la chaîne pour correspondre
  2. Appliquer votre motif « renversée », à l’aide d’une recherche avancée (faire attention à l’expression correspondante inverse à l’intérieur de la préanalyse, dans ce cas, il reste le même)
  3. inverser tous les jetons correspondants

38 votes

Le problème de cette approche est qu'elle ne fonctionne pas lorsque l'on a à la fois un lookahead et un lookbehind

3 votes

Pouvez-vous nous montrer un exemple de fonctionnement, disons que je veux faire correspondre max-height mais pas line-height et je veux seulement que le match soit height

1 votes

Il n'est pas utile de remplacer deux symboles identiques consécutifs (pas plus de deux) qui ne sont pas précédés d'un autre symbole. ''(?!\() remplacera les apostrophes dans ''(''test'''''''test de l'autre côté, laissant ainsi (''test'NNNtest plutôt que (''testNNN'test .

41voto

Jason S Points 58434

La stratégie de Mijoja fonctionne dans votre cas particulier, mais pas en général :

js>newString = "Fall ball bill balll llama".replace(/(ba)?ll/g,
   function($0,$1){ return $1?$0:"[match]";});
Fa[match] ball bi[match] balll [match]ama

Voici un exemple où l'objectif est de faire correspondre un double-l mais pas s'il est précédé de "ba". Notez le mot "balll" -- le vrai lookbehind aurait dû supprimer les 2 premiers l mais faire correspondre la 2ème paire. Mais en faisant correspondre les 2 premiers l et en ignorant ensuite cette correspondance comme un faux positif, le moteur de regexp procède à partir de l'élément fin de cette correspondance, et ignore tous les caractères contenus dans le faux positif.

6 votes

Ah, vous avez raison. Cependant, je suis beaucoup plus près du but que je ne l'étais auparavant. Je peux l'accepter jusqu'à ce que quelque chose de mieux arrive (comme l'implémentation de lookbehinds par javascript).

33voto

Mijoja Points 528

Utilisation

newString = string.replace(/([abcdefg])?m/, function($0,$1){ return $1?$0:'m';});

10 votes

Cela ne sert à rien : newString sera toujours égal à string . Pourquoi tant de votes positifs ?

0 votes

@MikeM : parce qu'il s'agit simplement de démontrer une technique d'appariement.

59 votes

@bug. Une démonstration qui ne fait rien est une drôle de démonstration. La réponse donne l'impression d'avoir été simplement copiée et collée sans que l'on comprenne comment elle fonctionne. D'où l'absence d'explication et l'incapacité à démontrer que quelque chose a été mis en correspondance.

13voto

Krof Drakula Points 5065

Vous pouvez définir un groupe non capturant en annulant votre jeu de caractères :

(?:[^a-g])m

...qui correspondrait à chaque m PAS précédé de l'une de ces lettres.

2 votes

Je pense que le match couvrirait également le personnage précédent.

5 votes

^ c'est vrai. Une classe de personnage représente... un personnage ! Tout ce que fait votre groupe de non-capture, c'est de ne pas rendre cette valeur disponible dans un contexte de remplacement. Votre expression ne dit pas "chaque m NON précédé par l'une de ces lettres", elle dit "chaque m précédé d'un caractère qui n'est PAS l'une de ces lettres"

6 votes

Pour que la réponse résolve également le problème d'origine (début de la chaîne), elle doit également inclure une option, de sorte que l'expression rationnelle résultante serait la suivante (?:[^a-g]|^)m . Voir regex101.com/r/jL1iW6/2 pour un exemple de fonctionnement.

-1voto

Techsin Points 162

/(?![abcdefg])[^abcdefg]m/gi Oui, il s'agit d'une astuce.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X