2017-10-28 49 views
5

Załóżmy, że mamy regularny wzór fleksyjny, którego nie można podzielić na segmenty. Na przykład. może to być infiksacja (dodanie kilku liter wewnątrz słowa) lub zmiana samogłosek ("ablaut"). Rozważ przykład z języka niemieckiego.Czy mogę zmodyfikować dosłownego wyrażenie w Perlu 6?

my @words = <Vater Garten Nagel>; 
my $search = "/@words.join('|')/".EVAL; 

"mein Vater" ~~ $search;        
say $/; # 「Vater」 

Wszystkie trzy niemieckie słowa mnoga zmieniając ich 2nd literę „A” do „a”. Tak więc "Vater" → "Väter", "Garten" → "Gärten", "Nagel" → "Nägel".

Czy istnieje sposób modyfikacji mojego wyrażenia regularnego $search, aby pasował do liczby mnogiej? Oto co szukam:

my $search_ä = $search.mymethod; 
"ihre Väter" ~~ $search_ä; 
say $/; # 「Väter」 

Oczywiście, można zmodyfikować tablicę @words „i” precompile go do nowego regex. Ale byłoby lepiej (jeśli to możliwe) bezpośrednio zmodyfikować istniejący regex.

+1

Należy zoptymalizować tylko po otrzymaniu go stan roboczy i po ustaleniu twojego kodu nie jest wystarczająco szybki. –

+0

@BradGilbert, jakie są ewentualne wady korzystania z tej optymalizacji domyślnie (ogólnie, pracuję z setkami kluczy wyszukiwania i ogromnymi korpusami tekstowymi, więc bez tej optymalizacji jest to naprawdę powolne)? Z wyjątkiem tego, że kod jest mniej elastyczny i mniej elegancki. –

Odpowiedz

7

Nie możesz.

Regeksy są obiektami kodu w Perlu 6. Twoje pytanie brzmi: "Czy mogę zmodyfikować podprogramy lub metody po ich napisaniu?". Odpowiedź jest taka sama dla tradycyjnych obiektów kodu i dla wyrażeń regularnych: nie, napisz je, na co chcesz.

To powiedziawszy, w rzeczywistości nie potrzebujesz EVAL dla Twojego przypadku użycia. Podczas korzystania zmienną tablicową wewnątrz regex, to jest interpolowana jako lista alternatywnych gałęzi, więc można po prostu napisać:

my @words = <Vater Garten Nagel>; my $search = /@words/;

regex $search staje zamknięcie, więc jeśli zmodyfikować @words, można również zmień co pasuje do $search.

Innym podejściem do tego konkretnego przykładu byłoby użyć modyfikatora :ignoremark, co sprawia a również dopasować ä (choć także wiele innych form, takich jak ā lub ǎ.)

+1

Dzięki za wyjaśnienie! Jeśli chodzi o moje użycie 'EVAL' zamiast'/@ words/', problem polega na tym, że z prawdziwymi danymi moja tablica wyszukiwania' @ words' zwykle zawiera kilkaset kluczy. Więc jeśli nie "skompiluję" ich z 'EVAL', program stanie się naprawdę wolny. Zadałem kilka pytań na temat tego problemu, więc jeśli istnieje lepsze rozwiązanie, proszę dać mi znać. ① [Szybkość Regex] (https://stackoverflow.com/questions/46867216/regex-speed-in-perl-6) ② [Filtrowanie tablicy] (https://stackoverflow.com/questions/46933838/filtering-elements -of-tablica-z-elementami-in-tablicy-in-perl-6) –