Jak reprezentowany jest operator AND / OR w wyrażeniach regularnych?

220

Obecnie programuję algorytm słownictwa, który sprawdza, czy użytkownik wpisał słowo poprawnie. Mam następującą sytuację: Prawidłowym rozwiązaniem dla tego słowa byłoby „część 1, część 2”. Użytkownik powinien być w stanie wpisać „część 1” (odpowiedź 1), „część 2” (odpowiedź 2) lub „część 1, część 2” (odpowiedź 3). Teraz próbuję dopasować ciąg podany przez użytkownika do następującego, automatycznie utworzonego wyrażenia regularnego:

^(part1|part2)$

To zwraca tylko odpowiedź 1 i 2 jako poprawną, podczas gdy odpowiedź 3 byłaby błędna. Zastanawiam się teraz, czy istnieje operator podobny do | to mówi and/orzamiast either...or.

Czy ktoś może mi pomóc rozwiązać ten problem?

Jonathan
źródło
1
Wyrażenia regularne mogą nie być najlepszym rozwiązaniem. Użyłbym normalnych metod łańcuchowych.
Felix Kling,
3
Ten problem jest źle określony. Dlaczego używasz dopasowania wzorca, gdy wszystko, czego potrzebujesz, to dokładne porównanie ciągu znaków z zestawem ciągów prawnych? O ile twój kompilator wyrażeń regularnych nie zoptymalizuje alternatywnych struktur trie O (1) w taki sposób, jak robi to Perl, prawdopodobnie powinieneś zamiast tego przeprowadzić test na członkostwo hashowe. Inne silniki wyrażeń regularnych nie są w tym zbyt sprytne.
tchrist
@tchrist Przypadkiem użycia może być dopasowanie $orwyrażenia regularnego mongodb
Nadir Abbas

Odpowiedzi:

284

Zakładam, że chcesz dynamicznie budować wyrażenie regularne tak, aby zawierało inne słowa niż część 1 i część 2, i że porządek nie ma znaczenia. Jeśli tak, możesz użyć czegoś takiego:

((^|, )(part1|part2|part3))+$

Pozytywne dopasowania:

part1
part2, part1
part1, part2, part3

Negatywne dopasowania:

part1,           //with and without trailing spaces.
part3, part2, 
otherpart1
Gaute Løken
źródło
4
Zauważ, że „część 1, część” 1 również będzie dodatnia. Co nie zawsze jest pożądane
dimaaan
1
@dimaaan Czy zgubiłeś swoje cytaty? „część 1, część 1” będzie pasować, ale „część 1, część” nie będzie. Chociaż masz rację, że taki scenariusz nie jest objęty tym rozwiązaniem, w przypadku zastosowania OP, w którym sprawdza, czy łańcuch testowy składa się ze słów w słowniku, wierzę, że chce pozytywnego dopasowania, nawet jeśli słowo jest powtarzający się. Słowo nadal będzie częścią słownika, bez względu na to, ile wystąpień masz.
Gaute Løken,
30
'^(part1|part2|part1,part2)$'

Czy to działa?

Kent
źródło
1
Oczywiście. regex wymaga dopasowania całego łańcucha (^, $)
glasspill
5

Czy to działa bez zmian?

^((part)1(, \22)?)?(part2)?$

a dlaczego nie to?

^((part)1(, (\22))?)?(\4)?$

Pierwszy działa dla wszystkich warunków, drugi dla wszystkich oprócz part2(przy użyciu GNU sed 4.1.5)

potong
źródło
4

Nie jest ekspertem od wyrażeń regularnych, ale możesz to zrobić ^((part1|part2)|(part1, part2))$. Innymi słowy: „część 1 lub część 2 lub obie”

Czarny niedźwiedź
źródło
2

Lub możesz użyć tego:

^(?:part[12]|(part)1,\12)$
FailedDev
źródło