Les expressions régulières correspondent uniquement à des mots entiers


90

J'ai une expression regex que j'utilise pour trouver tous les mots d'un bloc de contenu donné, insensible à la casse, qui sont contenus dans un glossaire stocké dans une base de données. Voici mon modèle:

/($word)/i

Le problème est que si j'utilise des /(Foo)/imots tels Foodque les correspondances. Il doit y avoir des espaces ou une limite de mot des deux côtés du mot.

Comment puis-je modifier mon expression pour qu'elle corresponde uniquement au mot Foolorsqu'il s'agit d'un mot au début, au milieu ou à la fin d'une phrase?

Réponses:


120

Utilisez des limites de mots:

/\b($word)\b/i

Ou si vous recherchez "SPECTRE" comme dans l'exemple de Sinan Ünür:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i

1
J'étais en train de taper la version longue de cette réponse lorsque vous avez posté. :)
ZombieSheep

@RichardSimoes \b(<|>=)\bne correspond pas>=
alhelal

@RichardSimoes et \b[-|+][0-9]+\bcorrespondance +10dans 43E+10. Je ne veux pas des deux.
alhelal

Que faire si je veux rechercher un mot qui n'est pas ajouté ou qui ne figure dans aucun autre mot. alors cette logique ne fonctionnera pas
Prasanna Sasne

Comment quelqu'un obtiendrait-il les opérateurs de comparaison mathématique> = et <=?
AntonSack

50

Pour correspondre à n'importe quel mot entier, vous utiliseriez le modèle (\w+)

En supposant que vous utilisez PCRE ou quelque chose de similaire:

entrez la description de l'image ici

Capture d'écran ci-dessus tirée de cet exemple en direct: http://regex101.com/r/cU5lC2

Faire correspondre n'importe quel mot entier sur la ligne de commande avec (\w+)

J'utiliserai le shell interactif phpsh sur Ubuntu 12.10 pour démontrer le moteur d' expression régulière PCRE via la méthode connue sous le nom de preg_match

Démarrez phpsh, mettez du contenu dans une variable, faites correspondre le mot.

el@apollo:~/foo$ phpsh

php> $content1 = 'badger'
php> $content2 = '1234'
php> $content3 = '$%^&'

php> echo preg_match('(\w+)', $content1);
1

php> echo preg_match('(\w+)', $content2);
1

php> echo preg_match('(\w+)', $content3);
0

La méthode de preg_match utilisé le moteur de PCRE dans le langage PHP pour analyser les variables: $content1, $content2et $content3avec le (\w)+motif.

$ content1 et $ content2 contiennent au moins un mot, $ content3 n'en contient pas.

Faites correspondre un certain nombre de mots littéraux sur la ligne de commande avec (dart|fart)

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(dart|fart)', $gun1);
1

php> echo preg_match('(dart|fart)', $gun2);
1

php> echo preg_match('(dart|fart)', $gun3);
1

php> echo preg_match('(dart|fart)', $gun4);
0

Les variables gun1 et gun2 contiennent la chaîne dart ou fart. gun4 ne le fait pas. Cependant, la recherche de fartcorrespondances de mots peut poser un problème farty. Pour résoudre ce problème, appliquez les limites des mots dans regex.

Faites correspondre les mots littéraux sur la ligne de commande avec les limites des mots.

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(\bdart\b|\bfart\b)', $gun1);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun2);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun3);
0

php> echo preg_match('(\bdart\b|\bfart\b)', $gun4);
0

Il est donc le même que l'exemple précédent , sauf que le mot fartavec une \blimite de mot n'existe pas dans le contenu: farty.


am, pm ce ne sont pas des mots?
minion

Si vous voulez forcer am et pm à être des mots (ce ne sont pas des acronymes), ajoutez un point comme caractère de mot pour votre moteur d'expression régulière. Pour vous, il semble que vous ayez défini le point comme un caractère de mot, donc les mots regex ne seront pas un-à-un pour la définition standard de "mot" qui vous a été enseignée dans votre dictionnaire européen pour votre européen hybride langue (ou toute autre langue d'ailleurs).
Eric Leschinski

8

L'utilisation \bpeut donner des résultats surprenants. Vous feriez mieux de comprendre ce qui sépare un mot de sa définition et d'incorporer cette information dans votre modèle.

#!/usr/bin/perl

use strict; use warnings;

use re 'debug';

my $str = 'S.P.E.C.T.R.E. (Special Executive for Counter-intelligence,
Terrorism, Revenge and Extortion) is a fictional global terrorist
organisation';

my $word = 'S.P.E.C.T.R.E.';

if ( $str =~ /\b(\Q$word\E)\b/ ) {
    print $1, "\n";
}

Production:

Compilation de REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Programme final:
   1: LIÉ (2)
   2: OUVERT1 (4)
   4: EXACT (9)
   9: FERMER1 (11)
  11: LIÉ (12)
  12: FIN (0)
"SPECTRE" ancré à 0 (vérification ancrée) stclass BOUND minlen 14
Deviner le début de la correspondance dans sv pour REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contre "SP
.ECTRE (Special Executive for Counter-Intelligence, "...
Substrat "SPECTRE" ancré trouvé au décalage 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Ne contredit pas STCLASS ...
Deviné: correspondance au décalage 0
Correspondance REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contre "SPECTRE (Exec spécial
utive pour le contre-espionnage, "...
   0 | 1: LIÉ (2)
   0 | 2: OUVERT1 (4)
   0 | 4: EXACT (9)
  14 | 9: FERMER1 (11)
  14 | 11: LIÉ (12)
                                  échoué...
Match échoué
Libération de REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"

1
Je pense qu'un mot sera typiquement un mot \ w, mais un point intéressant.
Richard Simões

1

utiliser des limites de mots \ b,

Ce qui suit (en utilisant quatre échappements) fonctionne dans mon environnement: Mac, Safari Version 10.0.3 (12602.4.8)

var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)

1

Pour ceux qui veulent valider un Enum dans leur code, vous pouvez suivre le guide

Dans Regex World, vous pouvez utiliser ^pour démarrer une chaîne et la $terminer. Les utiliser en combinaison avec |pourrait être ce que vous voulez:

^(Male)$|^(Female)$

Il ne retournera vrai que pour Maleou Femalecas.


^et $correspond au début (respectivement à la fin) d'une ligne, donc votre exemple ne correspondra que si ce sont les seuls mots de la ligne.
gented

et c'est exactement ce que je veux quand je veux valider une énumération! quel est le problème?
MohamadrezaRahimianGolkhandani

0

Si vous le faites dans Notepad ++

[\w]+ 

Vous donnerait le mot entier, et vous pouvez ajouter des parenthèses pour l'obtenir en tant que groupe. Exemple: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Je voudrais passer LeakyReLUà sa propre ligne en tant que commentaire, et remplacer l'activation actuelle. Dans notepad ++, cela peut être fait en utilisant la commande suivante:

([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)

et la commande replace devient:

\1\2'relu'\4 \n    # \1 = LeakyReLU\(alpha=a\)\(\1\)

Les espaces sont pour garder le bon formatage dans mon code. :)


-1

Récupère tous les "mots" dans une chaîne

/([^\s]+)/g

En gros, cela ^/ssignifie casser sur des espaces (ou faire correspondre des groupes de non-espaces)
N'oubliez pas le gpour Greedy

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.