Regex dopasowuje tylko całe słowa

90

Mam wyrażenie regularne, którego używam, aby znaleźć wszystkie słowa w danym bloku treści, bez rozróżniania wielkości liter, które są zawarte w glosariuszu przechowywanym w bazie danych. Oto mój wzór:

/($word)/i

Problem polega na tym, że jeśli /(Foo)/iużyję słów takich jak „ Fooddopasuj”. Po obu stronach słowa musi znajdować się spacja lub granica słowa.

Jak mogę zmodyfikować wyrażenie, aby dopasować tylko słowo, Foogdy jest to słowo na początku, w środku lub na końcu zdania?

Aaron
źródło

Odpowiedzi:

120

Użyj granic słów:

/\b($word)\b/i

Lub jeśli szukasz „SPECTER”, jak w przykładzie Sinana Ünür:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i
Richard Simões
źródło
1
Właśnie pisałem długą wersję tej odpowiedzi, kiedy opublikowałeś. :)
ZombieSheep
@RichardSimoes \b(<|>=)\bnie pasuje>=
alhelal
@RichardSimoes i \b[-|+][0-9]+\bmecz +10w 43E+10. Obie nie chcę.
alhelal
co jeśli chcę wyszukać słowo, które nie jest dołączone lub nie występuje w żadnym innym słowie. wtedy ta logika nie zadziała
Prasanna Sasne
Jak ktoś mógłby uzyskać matematyczne operatory porównania> = i <=?
AntonSack
50

Aby dopasować całe słowo, użyjesz wzorca (\w+)

Zakładając, że używasz PCRE lub czegoś podobnego:

wprowadź opis obrazu tutaj

Powyższy zrzut ekranu pochodzi z tego przykładu na żywo: http://regex101.com/r/cU5lC2

Dopasowanie całego słowa w linii poleceń za pomocą (\w+)

Będę za pomocą phpsh interaktywną powłokę na Ubuntu 12.10 do wykazania silnik PCRE regex za pomocą metody znanej jako preg_match

Uruchom phpsh, umieść treść w zmiennej, dopasuj słowo.

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

Metoda preg_match używany silnik PCRE w języku PHP do analizy zmiennych: $content1, $content2i $content3ze (\w)+wzorca.

$ content1 i $ content2 zawierają co najmniej jedno słowo, $ content3 nie.

Dopasuj kilka dosłownych słów w wierszu poleceń za pomocą (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

zmienne gun1 i gun2 zawierają strzałkę lub pierdnięcie. gun4 tego nie robi. Jednak problemem może być szukanie fartdopasowań słów farty. Aby to naprawić, wymuszaj granice słów w wyrażeniu regularnym.

Dopasuj dosłowne słowa w wierszu poleceń z granicami słów.

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

Więc to jest taka sama, jak w poprzednim przykładzie, z wyjątkiem, że słowo fartz \bgranicy słowo nie istnieje w treści: farty.

Eric Leschinski
źródło
am, pm to nie słowa?
sługus
Jeśli chcesz wymusić słowa am i pm jako słowa (nie są to akronimy), dodaj kropkę jako znak słowa dla silnika wyrażeń regularnych. Wydaje się, że ustawiłeś kropkę jako nie znak słowa, więc wyrazy wyrażenia regularnego nie będą miały charakteru „jeden do jednego” i „na” dla standardowej definicji „słowa”, której nauczono Cię w Słowniku europejskim dla hybrydowego europejskiego słownika język (lub jakikolwiek inny język).
Eric Leschinski
8

Używanie \bmoże przynieść zaskakujące rezultaty. Lepiej byłoby dowiedzieć się, co oddziela słowo od jego definicji i uwzględnić tę informację w swoim wzorcu.

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

Wynik:

Kompilowanie REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Program końcowy:
   1: ZWIĄZANE (2)
   2: OTWARTE1 (4)
   4: DOKŁADNE (9)
   9: ZAMKNIJ1 (11)
  11: BOUND (12)
  12: KONIEC (0)
zakotwiczony "SPECTER" na 0 (sprawdzanie zakotwiczony) stclass BOUND minlen 14
Odgadywanie początku dopasowania w sv dla REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" przeciwko "SP
.ECTRE (Specjalny Wykonawca ds. Kontrwywiadu, „...
Znaleziono zakotwiczony substrat „SPECTER” z przesunięciem 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Nie zaprzecza STCLASS ...
Zgadnięty: dopasowanie na przesunięciu 0
Dopasowanie REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" do "SPECTER (Special Exec
przydatne dla kontrwywiadu, „...
   0 | 1: ZWIĄZANE (2)
   0 | 2: OTWARTE1 (4)
   0 | 4: DOKŁADNE (9)
  14 | 9: ZAMKNIJ1 (11)
  14 | 11: POWIĄZANE (12)
                                  nie powiodło się ...
Dopasowanie nie powiodło się
Uwalnianie REx: „\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B”
Sinan Ünür
źródło
1
Myślę, że słowo będzie zwykle słowem \ w, ale interesującym punktem.
Richard Simões
1

użyj granic słów \ b,

Następujące (przy użyciu czterech ucieczek) działa w moim środowisku: Mac, Safari w wersji 10.0.3 (12602.4.8)

var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)
X. L
źródło
1

Dla tych, którzy chcą zweryfikować Enum w swoim kodzie, możesz postępować zgodnie z przewodnikiem

W Regex World możesz użyć ^do rozpoczęcia i $zakończenia łańcucha . Używanie ich w połączeniu z |może być tym, czego chcesz:

^(Male)$|^(Female)$

Zwróci prawdę tylko dla przypadku Malelub Female.

MohamadrezaRahimianGolkhandani
źródło
^i $dopasuj początek (odpowiednio koniec) wiersza, dlatego przykład będzie pasował tylko wtedy, gdy będą to jedyne słowa w wierszu.
gented
i właśnie tego chcę, gdy chcę sprawdzić poprawność wyliczenia! Jaki jest problem?
MohamadrezaRahimianGolkhandani
0

Jeśli robisz to w Notepad ++

[\w]+ 

Dałoby ci całe słowo i możesz dodać nawiasy, aby uzyskać je jako grupę. Przykład: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Chciałbym przejść LeakyReLUdo osobnej linii jako komentarz i zastąpić obecną aktywację. W Notatniku ++ można to zrobić za pomocą następującego polecenia find:

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

a polecenie zamień staje się:

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

Spacje mają zachować właściwe formatowanie w moim kodzie. :)

JTIM
źródło
-1

Zbierz wszystkie „słowa” w ciągu

/([^\s]+)/g

Zasadniczo ^/soznacza łamanie spacji (lub dopasowywanie grup bez spacji).
Nie zapomnij o gfor Greedy

gdibble
źródło