2015-04-18 17:16:31 +0000 2015-04-18 17:16:31 +0000
20
20

Jak napisać regeksa, by pasował do konkretnego słowa?

Próbowałem sprawić, by konkretny regex działał, ale nie mogę sprawić, by robił to, co trzeba.

W zasadzie chcę, by szukał ROCKETU. Regex powinien pasować do ROCKET'a w górnych lub dolnych literach, z interpunkcją lub bez, ale nie gdy jest częścią innego słowa. Tak więc, regex wyzwalałby na którymkolwiek z nich:

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

ale nie wyzwalałby na ROCKET'ie, gdy znajdzie się w czymś takim jak

Rocketeer
Sprocket

Próbowałem to naprawić używając generatora regex'owego online, ale nie mogę go dopasować dokładnie.

Odpowiedzi (4)

11
11
11
2015-04-18 17:32:40 +0000

Sugeruję dodanie do zakładek MSDN Regular Expression Quick Reference

, aby uzyskać nieczuły na wielkość liter wyraz “rakieta” otoczony niealfanumerycznymi znakami. Regex, który by zadziałał to:

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

Co to da, to szukanie zera lub więcej (*) znaków niealfanumerycznych (\W), po których następuje niewrażliwa na wielkość liter wersja rakiety (?i)rakiety(?-i)), po których następuje ponownie zero lub więcej (*) znaków niealfanumerycznych (\W). Dodatkowe nawiasy wokół terminu “rocket-matching” przypisują dopasowanie do osobnej grupy. Słowo rakieta będzie więc w grupie dopasowania 1.

UPDATE 1: Matt powiedział w komentarzu, że ten regex ma być użyty w pytonie. Python ma nieco inną składnię. Aby osiągnąć ten sam wynik w pythonie, użyj tego regexa i przekaż opcję re.IGNORECASE do funkcji compile lub match.

\W*(rocket)\W*

Na Regex101 można to zasymulować wpisując “i” w polu tekstowym obok wejścia regex.

UPDATE 2 Ismael wspomniał, że regex nie jest całkiem poprawny, ponieważ może pasować do “1 rakiety1”. Zamieścił znacznie lepsze rozwiązanie, a mianowicie

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

10
10
10
2015-04-19 06:17:43 +0000

Myślę, że look-aheads są w tym przypadku przesadzone, i lepiej byłoby użyć słów granicznych z opcją ignorecase,

\brocket\b

Innymi słowy, w pythonie:

>>> x="rocket's"
>>> y="rocket1."
>>> c=re.compile(r"\brocket\b",re.I) # with the ignorecase option
>>> c.findall(y)
[]
>>> c.findall(x)
['rocket']
1
1
1
2015-04-19 04:00:42 +0000

Z grep i sed, możesz użyć \<rocket\>.  Z grep, opcja -i sprawi, że wielkość liter będzie niewrażliwa ( i gnore case):

grep -i '\<rocket\>'

Nie znam żadnego sposobu, aby wszystkie sed regexy były niewrażliwe na wielkość liter, ale zawsze jest sposób jaskiniowca:

sed -n '/\<[Rr][Oo][Cc][Kk][Ee][Tt]\>/p'
0
0
0
2019-11-23 10:06:05 +0000

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

Jeśli chodzi o interpunkcję, nie możesz na nią odpowiedzieć, dopóki nie poznasz smaku/smaku.

Jest to bardzo stary wątek, więc umieszczony dla kogoś, kto może odwiedzić z potrzebą, później. Osoby, od których pochodzi wątek, mogły przenieść się do czegoś innego… Nie?