Wyrażenie regularne wykluczające słowo / ciąg

298

Mam wyrażenie regularne w następujący sposób:

^/[a-z0-9]+$

To pasuje do ciągów takich jak /hellolub/hello123 .

Chciałbym jednak wykluczyć kilka wartości łańcuchowych, takich jak /ignoremei /ignoreme2.

Wypróbowałem kilka wariantów, ale wydaje się, że żaden nie działa!

Moja ostatnia słaba próba była

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Każda pomoc będzie wdzięczna :-)

romiem
źródło
1
Możliwy duplikat: stackoverflow.com/questions/1395177/…
Anderson Green,

Odpowiedzi:

376

Oto jeszcze jeden sposób (przy użyciu negatywnego spojrzenia w przyszłość ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Uwaga: Jest tylko jeden wyraz przechwytywanie: ([a-z0-9]+).

Seth
źródło
1
Genialnie, wydaje się, że to załatwiło sprawę. Potrzebuję tej reguły do ​​przepisywania adresów URL i chciałem zignorować folder „images”, „css” i „js”. Więc moja reguła jest następująca: ^ / (?! css | js | images) ([az] +) /? (\? (. +))? $ I przepisuje do /Profile.aspx?id=$1&$3 Czy ta reguła będzie działać poprawnie i również propagować ciąg zapytania? Więc jeśli ktoś odwiedzi mydomain.com/hello?abc=123 Chciałbym, aby przepisał na mydomain.com/Profile.aspx?id=hello&abc=123 Nie jestem również pewien, czy wydajność (. +) W koniec przechwytywania kwerendy w pierwotnym żądaniu.
romiem
Wygląda na to, że to kolejne pytanie. Wyrażenie regularne, które wygląda tak, że przechwytuje ciąg zapytania - przetestuj i sprawdź, czy pojawi się ciąg zapytania. Również - (\?(.+))?$powinien być szybki. Nie martwiłbym się zbytnio szybkością.
Seth
1
Nie działało to dla mnie, podczas gdy rozwiązanie Alix Axel działało. Korzystam z java.util.regex.Patternklasy Java .
Mark Jeronimus
1
Potwierdzam znak Marka;) - na przykład Pycharm jest oparty na Javie, prawda? Tak więc, biorąc pod uwagę wyrażenia regularne w wyszukiwaniu Pycharm, rozwiązanie Alix działa, drugie nie.
fanny
43

To powinno to zrobić:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Możesz dodać tyle ignorowanych słów, ile chcesz, oto prosta implementacja PHP:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);
Alix Axel
źródło
myślałem, że obejrzenie się wymaga wzoru o stałej szerokości?
simon
2
@AlixAxel Tak, ale mądrzejsze biblioteki wyrażeń regularnych pozwolą na zmianę z różnymi długościami dla alternatyw (i używają najdłuższych), o ile każda alternatywa ma stałą długość.
ChrisF,
jest to mądre, ale dla mnie zawodzi, jeśli ignorowane słowo znajduje się na końcu dowolnego innego słowa. tzn. jeśli dodasz „a” jako jedno z ignorowanych słów, wówczas każde słowo, które kończy się na a, jest ignorowane
singmotor
21

Aby wykluczyć oba słowa, potrzebujesz koniugacji:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Teraz oba warunki muszą być spełnione (ani ignoreme, ani ignoreme2 nie są dozwolone), aby mieć dopasowanie.

Gumbo
źródło
1
Jest to równoważne z krótszym powyżej, który jest negatywnym spojrzeniem na zestaw alternatyw.
ChrisF,
4
@ChrisF Nie, nie bardzo. Rozwiązanie Setha nie będzie pasować do czegoś takiego /ignoremenotjak /następuje ignoreme.
Gumbo