Jak napisać wyrażenie regularne pasujące do określonego słowa?

21

Próbowałem uruchomić konkretny regex, ale nie mogę tego zrobić, aby zrobić to, czego potrzebuję.

Zasadniczo chcę, aby szukał ROCKET. Wyrażenie regularne powinno pasować do ROCKET wielkimi lub małymi literami oraz z interpunkcją lub bez, ale nie gdy jest częścią innego słowa. Zatem wyrażenie regularne uruchomi się na jednym z następujących:

rocket
RoCKEt
hi Rocket
This is a rocket.
ROCKET's engine

ale NIE uruchamia się w trybie ROCKET, gdy znajdzie się w czymś takim

Rocketeer
Sprocket

Próbowałem to zrobić poprawnie za pomocą internetowego generatora wyrażeń regularnych, ale nie mogę go dokładnie dopasować.

Kefka
źródło
1
Jest to jedna z tych [rzadkich] sytuacji, w których pytanie może być lepiej dostosowane do przepełnienia stosu. Podaj język i / lub platformę, ponieważ każdy język ma swoje osobliwości. Na przykład Windows. .Net i klasa Regex . (Zwykle jest na odwrót. Stack Overflow otrzymuje setki pytań nie na temat od deweloperów, które są bardziej odpowiednie dla Super User).
jww

Odpowiedzi:

14

Proponuję dodać do zakładek Skrócone omówienie wyrażeń regularnych MSDN

chcesz osiągnąć rozróżnianie wielkości liter w słowie „rakieta” w otoczeniu znaków innych niż alfanumeryczne. Wyrażenie regularne, które zadziałałoby, byłoby:

\W*((?i)rocket(?-i))\W*

Będzie szukał zera lub więcej (*) znaków niealfanumerycznych (\ W), po których nie będzie rozróżniana wielkość liter wersja rakiety ((? I) rakieta (? - i)), a następnie ponownie zero lub więcej ( *) znaki niealfanumeryczne (\ W). Dodatkowe nawiasy wokół terminu dopasowania rakiety przypisują dopasowanie do oddzielnej grupy. Słowo rakieta będzie zatem należeć do grupy meczów 1.

AKTUALIZACJA 1: Matt powiedział w komentarzu, że tego wyrażenia regularnego należy używać w pythonie. Python ma nieco inną składnię. Aby osiągnąć ten sam wynik w pythonie, użyj tego wyrażenia regularnego i przekaż re.IGNORECASEopcję do funkcji compilelub match.

\W*(rocket)\W*

Na Regex101 można to zasymulować, wprowadzając „i” w polu tekstowym obok wejścia wyrażenia regularnego.

AKTUALIZACJA 2 Ismael wspomniał, że wyrażenie regularne nie jest całkiem poprawne, ponieważ może pasować do „1rocket1”. Opublikował znacznie lepsze rozwiązanie, a mianowicie

(?:^|\W)rocket(?:$|\W)

Xaser
źródło
1
Testowanie tego za pomocą testerów wyrażeń regularnych online ( na przykład regex101.com ) pokazuje, że są one niepoprawne i nie pasują do przykładowych ciągów, które wprowadzam. Jest to przeznaczone do użycia jako część skryptu Pythona. Czy to wpływa na sposób, w jaki powinien być napisany?
Kefka,
1
tak. możesz zobaczyć na regex101.com, że możesz wybrać „smak” wyrażenia regularnego w lewym górnym rogu, python jest nieco inny. Zaktualizuję swoją odpowiedź odpowiednikiem w języku Python.
Xaser
1
Dzięki. Myślałem, że wyrażenia regularne były w zasadzie niezależne od języka.
Kefka
1
Powinny być, ale istnieją niewielkie różnice w implementacji.
Xaser
2
I \W*(rocket)\W*mecze lrocketl. Powinien być (?:^|\W)(rocket)(?:$|\W)(bez *i musisz sprawdzić, czy pasuje on do początku i / lub końca łańcucha).
Ismael Miguel
10

Myślę, że w tym przypadku przewidywania są nadmierne, a lepiej byłoby użyć granic słów z ignorecaseopcją,

\brocket\b

Innymi słowy, w python:

>>> x="rocket's"
>>> y="rocket1."
>>> c=re.compile(r"\brocket\b",re.I)  # with the ignorecase option
>>> c.findall(y)
[]
>>> c.findall(x)
['rocket']
beroe
źródło
technicznie, grupy nie przechwytujące nie są niczym innym, ale opcja / b daje dokładnie taki sam wynik jak rozwiązanie Ismael, ale może być nieco bardziej elegancka.
Xaser,
1

Za pomocą grepi sedmożesz używać \<rocket\>. Z grepThe -iopcja pozwoli wielkości liter ( I gnore przypadek):

grep -i '\<rocket\>'

Nie wiem, jak sprawić, by wszystkie sedwyrażenia regularne nie uwzględniały wielkości liter, ale zawsze istnieje sposób jaskiniowca:

sed -n '/\<[Rr][Oo][Cc][Kk][Ee][Tt]\>/p'
Scott
źródło
0

Użyj opcji Szukaj tylko całych słów.

Jeśli chodzi o interpunkcje, nie możesz odpowiedzieć, dopóki nie poznasz smaku / smaku.

To bardzo stary wątek, więc opublikowany dla kogoś, kto może odwiedzić z potrzebą, później. Ci, którzy stworzyli wątek, mogli przenieść się na coś innego ... Nie?

Rex Schweiss
źródło
Co whole words only optionużywa greplub php? Przepraszamy, ale twoja odpowiedź nie daje żadnej wartości dodanej w porównaniu z innymi odpowiedziami.
Toto