Le espressioni regolari corrispondono solo a parole intere


90

Ho un'espressione regex che sto usando per trovare tutte le parole in un dato blocco di contenuto, senza distinzione tra maiuscole e minuscole, che sono contenute in un glossario memorizzato in un database. Ecco il mio schema:

/($word)/i

Il problema è che se uso /(Foo)/iparole come Foodvengono abbinate. Deve esserci uno spazio bianco o un confine di parola su entrambi i lati della parola.

Come posso modificare la mia espressione in modo che corrisponda solo alla parola Fooquando è una parola all'inizio, al centro o alla fine di una frase?

Risposte:


120

Usa i confini delle parole:

/\b($word)\b/i

O se stai cercando "SPECTRE" come nell'esempio di Sinan Ünür:

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

1
Stavo solo scrivendo la versione a mano lunga di questa risposta quando hai pubblicato. :)
ZombieSheep

@RichardSimoes \b(<|>=)\bnon corrisponde>=
alhelal

@RichardSimoes e \b[-|+][0-9]+\bpartita +10in 43E+10. Entrambi non li voglio.
alhelal

cosa succede se voglio cercare una parola che non è aggiunta o non è contenuta in nessun'altra parola. allora questa logica non funzionerà
Prasanna Sasne

Come potrebbe qualcuno ottenere gli operatori di confronto matematico> = e <=?
AntonSack

50

Per abbinare qualsiasi parola intera dovresti usare il modello (\w+)

Supponendo che tu stia utilizzando PCRE o qualcosa di simile:

inserisci qui la descrizione dell'immagine

Schermata sopra presa da questo esempio dal vivo: http://regex101.com/r/cU5lC2

Abbinando qualsiasi parola intera sulla riga di comando con (\w+)

Sarò utilizzando la shell interattiva phpsh su Ubuntu 12.10 dimostrare il motore PCRE regex attraverso il metodo noto come preg_match

Avvia phpsh, metti del contenuto in una variabile, abbina 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

Il metodo preg_match utilizzato il motore PCRE all'interno del linguaggio PHP per analizzare le variabili: $content1, $content2e $content3con il (\w)+modello.

$ content1 e $ content2 contengono almeno una parola, $ content3 no.

Abbina un numero di parole letterali sulla riga di comando con (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

le variabili gun1 e gun2 contengono la stringa dart o fart. gun4 no. Tuttavia può essere un problema che la ricerca di fartcorrispondenze di parole farty. Per risolvere questo problema, applica i confini delle parole nella regex.

Abbina le parole letterali sulla riga di comando con i confini delle parole.

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

Quindi è la stessa dell'esempio precedente, tranne che la parola fartcon un \blimite di parola non esiste nel contenuto: farty.


am, pm non sono parole?
minion

Se vuoi forzare am e pm come parole (non lo sono, sono acronimi), aggiungi il punto come carattere della parola per il tuo motore regex. Per te sembra che tu abbia impostato il punto non come un carattere di una parola, quindi quindi le parole regex non saranno uno a uno per la definizione standard di "parola" che ti è stata insegnata nel tuo dizionario europeo per il tuo europeo ibrido lingua (o qualsiasi altra lingua per quella materia).
Eric Leschinski

8

L'utilizzo \bpuò produrre risultati sorprendenti. Faresti meglio a capire cosa separa una parola dalla sua definizione e incorporare quell'informazione nel tuo schema.

#!/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";
}

Produzione:

Compilazione REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Programma finale:
   1: BOUND (2)
   2: OPEN1 (4)
   4: ESATTO (9)
   9: CHIUDI1 (11)
  11: VINCOLATO (12)
  12: FINE (0)
ancorato "SPECTRE" a 0 (controllo ancorato) stclass BOUND minlen 14
Indovinare l'inizio della partita in sv per REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contro "SP
.ECTRE (Dirigente speciale per il controspionaggio, "...
Trovato substr ancorato "SPECTRE" all'offset 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Non contraddice STCLASS ...
Indovinato: partita all'offset 0
Corrispondenza REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contro "SPECTRE (Special Exec
utivo per Counter-intelligence, "...
   0 | 1: BOUND (2)
   0 | 2: OPEN1 (4)
   0 | 4: ESATTO (9)
  14 | 9: CHIUDI1 (11)
  14 | 11: VINCOLATO (12)
                                  fallito ...
Partita fallita
Liberare REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"

1
Penso che una parola sarà tipicamente una \ w parola, ma un punto interessante.
Richard Simões

1

usa i confini delle parole \ b,

Quanto segue (utilizzando quattro escape) funziona nel mio ambiente: Mac, versione safari 10.0.3 (12602.4.8)

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

1

Per coloro che vogliono convalidare un Enum nel proprio codice è possibile seguire la guida

In Regex World puoi usare ^per iniziare e $terminare una stringa . Usarli in combinazione con |potrebbe essere quello che vuoi:

^(Male)$|^(Female)$

Restituirà true solo per Maleo Femalecase.


^e $corrisponde all'inizio (rispettivamente alla fine) di una riga, quindi il tuo esempio corrisponderebbe solo se quelle sono le uniche parole nella riga.
gented

e questo è esattamente quello che voglio quando voglio convalidare un enum! qual è il problema?
MohamadrezaRahimianGolkhandani

0

Se lo stai facendo in Notepad ++

[\w]+ 

Ti darebbe l'intera parola e puoi aggiungere parentesi per ottenerla come gruppo. Esempio: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Vorrei passare LeakyReLUa una riga a parte come commento e sostituire l'attivazione corrente. In Notepad ++ questo può essere fatto usando il seguente comando find:

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

e il comando di sostituzione diventa:

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

Gli spazi servono a mantenere la giusta formattazione nel mio codice. :)


-1

Ottieni tutte le "parole" in una stringa

/([^\s]+)/g

Fondamentalmente ^/ssignifica rompere gli spazi (o abbinare gruppi di non spazi)
Non dimenticare il gper Greedy

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.