2016-11-13 15 views
6

Próbuję utworzyć regex, który pasuje trzecią formę osobową czasownika utworzonego stosując następującą zasadę:Regex dla trzeciej osoby czasownika

Jeżeli czasownik kończy się e nie poprzedzonego I, o, s, x, z, ch, sh, dodaj s.

Więc szukam regex pasujące słowo składające się z kilku liter, następnie nie I, O, S, X, Z, ch, sh, a następnie "es". Próbowałem to:

\b\w*[^iosxz(sh)(ch)]es\b 

Według regex101 pasuje „lubi”, „nienawidzi” itd. Jednak to nie pasuje „wanny”, to dlaczego nie?

+2

'[^ iosxz (sh) (ch)]' nie robić to, co myślisz, że to robi. Jest to odpowiednik '[^ chiosxz()]'. – Biffen

+0

* Jeśli rzeczownik kończy się na e, a nie jest poprzedzony i, o, s, x, z, ch, sh * - co powiesz na "dom", to przychodzi do "domów"? – RomanPerekhrest

+0

@RomanPerekhrest - Chciałem napisać "czasownik w formie trzeciej osoby". Przepraszam za zamieszanie. Co więcej, ta konkretna reguła ma pasować tylko do małej (ish) części wszystkich czasowników. – maestromusica

Odpowiedz

2

Można użyć

\b(?=\w*(?<![iosxz])(?<![cs]h)es\b)\w* 

Zobacz regex demo

Od Python re nie obsługuje zmienne alternatywy długości w lookbehind, trzeba podzielić na dwie lookbehinds warunki tutaj.

Wzór szczegóły:

  • \b - czołowy słowo granica
  • (?=\w*(?<![iosxz])(?<![cs]h)es\b) - pozytywny uprzedzona wymaga sekwencji:
    • \w* - 0+ słowo znaków
    • (?<![iosxz]) - nie może być i, o , s, x, z znaków tuż przed bieżącej lokalizacji i ...
    • (?<![cs]h) - nie ch lub sh tuż przed bieżącej lokalizacji ...
    • es - następuje z es ...
    • \b - na koniec słowo
  • \w* - zero lub więcej (może + jest tu lepiej dopasować 1 lub więcej) znaków tekstowych.

Zobacz Python demo:

import re 
r = re.compile(r'\b(?=\w*(?<![iosxz])(?<![cs]h)es\b)\w*') 
s = 'it matches "likes", "hates" etc. However, it does not match "bathes", why doesn\'t it?' 
print(re.findall(r, s)) 
1

Jeśli chcesz dopasować ciągi, które kończą się e i nie są poprzedzone i, o, s, x, z, ch, sh, należy użyć:

(?<!i|o|s|x|z|ch|sh)e 

Twój regex [^iosxz(sh)(ch)] składa character group , ^ po prostu neguje, a reszta będzie dokładnie dopasowana, więc jest to odpowiednik:

[^io)sxz(c] 

co właściwie oznacza: "dopasuj wszystko, co nie jest jednym z" io) sxz (c ".

+1

Twoje ['(?

+0

@ WiktorStribiżew Napisałem czyste wyrażenie, niezależnie od języka programowania. – Maroun

+4

Nie ma czegoś takiego jak "czysty" regex. Twoje '(?