match Regex mots entiers seulement
-
20-09-2019 - |
Question
J'ai une expression regex que j'utilise pour trouver tous les mots dans un même bloc de contenu, 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, si j'utilise /(Foo)/i
alors des mots comme Food
se correspondent. Il doit y avoir des espaces limites ou un mot sur les deux côtés du mot.
Comment puis-je modifier mon expression pour correspondre uniquement le mot Foo
quand il est un mot au début, au milieu ou à la fin d'une phrase?
La solution
Utilisez des limites de mots:
/\b($word)\b/i
Ou si vous recherchez « S.P.E.C.T.R.E. » comme dans l'exemple de Sinan Unur:
/(?:\W|^)(\Q$word\E)(?:\W|$)/i
Autres conseils
Pour faire correspondre un mot entier vous utilisez le modèle (\w+)
En supposant que vous utilisez PCRE ou quelque chose de similaire:
Au-dessus de capture d'écran tirée de cet exemple en direct: http://regex101.com/r/cU5lC2
tout assorti mot entier sur la ligne de commande avec (\w+)
Je vais utiliser la phpsh shell interactif sur Ubuntu 12.10 pour démontrer la PCRE moteur regex par le procédé connu sous le nom preg_match
Lancer phpsh, mettre un peu de contenu dans une variable, match sur parole.
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 PCRE dans le langage PHP pour analyser les variables: $content1
, $content2
et $content3
avec le motif de (\w)+
.
$ content1 et content2 $ contiennent au moins un mot, content3 de $ ne fonctionne pas.
Faites correspondre un certain nombre de mots littéral 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 le dard de chaîne ou péter. gun4 ne fonctionne pas. Cependant, il peut être un problème que la recherche de mot fart
correspond farty
. Pour résoudre ce problème, respecter les limites de mots dans regex.
Faites correspondre les mots littéraux sur la ligne de commande avec des limites de 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 fart
avec une limite de mot de \b
n'existe pas dans le contenu: farty
.
L'utilisation \b
peut donner des résultats surprenants. Vous seriez mieux déterminer ce qui sépare un mot de sa définition et en incorporant ces informations dans votre schéma.
#!/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";
}
Sortie:
Compiling REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" Final program: 1: BOUND (2) 2: OPEN1 (4) 4: EXACT (9) 9: CLOSE1 (11) 11: BOUND (12) 12: END (0) anchored "S.P.E.C.T.R.E." at 0 (checking anchored) stclass BOUND minlen 14 Guessing start of match in sv for REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P .E.C.T.R.E. (Special Executive for Counter-intelligence,"... Found anchored substr "S.P.E.C.T.R.E." at offset 0... start_shift: 0 check_at: 0 s: 0 endpos: 1 Does not contradict STCLASS... Guessed: match at offset 0 Matching REx "\b(S\.P\.E\.C\.T\.R\.E\.)\b" against "S.P.E.C.T.R.E. (Special Exec utive for Counter-intelligence,"... 0 | 1:BOUND(2) 0 | 2:OPEN1(4) 0 | 4:EXACT (9) 14 | 9:CLOSE1(11) 14 | 11:BOUND(12) failed... Match failed Freeing REx: "\b(S\.P\.E\.C\.T\.R\.E\.)\b"
limites; mot \ b,
Les suivants (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’)
Si vous le faites dans Notepad ++
[\w]+
Souhaitez-vous donner le mot entier, et vous pouvez ajouter des parenthèses pour 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
dans sa propre ligne comme un commentaire, et remplacer l'activation en cours. Dans notepad ++ cela peut être fait en utilisant la commande find suit:
([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)
et remplacer la commande devient:
\1\2'relu'\4 \n # \1 = LeakyReLU\(alpha=a\)\(\1\)
Les espaces est de garder la mise en forme à droite dans mon code. :)