2017-10-28 95 views
5

假設我們有一個規則的折點模式,它不能被拆分成段。例如。它可以是中綴(在單詞內部添加一些字母)或元音變化('ablaut')。考慮德國人的一個例子。我可以在Perl 6中修改文字正則表達式嗎?

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

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

這三個德語單詞組成,通過改變他們的第二個字母「A」至「A」複數。所以'Vater'→'Väter','Garten'→'Gärten','Nagel'→'Nägel'。

有沒有辦法修改我的$search正則表達式,使它匹配複數形式? 這裏就是我在尋找:

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

當然,我可以修改@words陣列和「預編譯」成一個新的regex。但是如果可能的話,直接修改現有的regex會更好。

+1

你只應該是讓後優化一個工作狀態和確定你的代碼後不夠快。 –

+0

@BradGilbert,默認情況下使用這種優化可能有什麼缺點(一般來說,我使用數百個搜索關鍵字和大量文本語料庫,所以如果沒有這種優化,它真的很慢)?除了代碼不夠靈活和不太優雅外。 –

回答

7

你不能。

正則表達式是Perl 6中的代碼對象。因此,您的問題基本上顯示爲「我可以在寫入它們之後修改子例程或方法嗎?」。對於傳統的代碼對象和正則表達式,答案是一樣的:不,將它們寫在你想要的第一個地方。

這就是說,你實際上並不需要EVAL你的用例。當您使用正則表達式中的數組變量,它被插值爲選擇分支的列表,所以你可以這樣寫:

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

正則表達式$search成爲一個封閉的,所以如果你修改@words,你也改變什麼$search匹配。

到這個特殊的例子另一種方法是使用:ignoremark修改,這使得a也匹配ä(雖然也是許多其他形式,如āǎ。)

+1

感謝您的澄清!至於我使用'EVAL'而不是'/ @ words /',問題在於,對於真實數據,我的'@ words'搜索數組通常包含幾百個鍵。所以如果我不用'EVAL''預編譯'它們,程序變得非常慢。我已經問過關於這個問題的幾個問題,所以如果有更好的解決方案,請讓我知道。 ①[正則表達式速度](https://stackoverflow.com/questions/46867216/regex-speed-in-perl-6)②[過濾數組](https://stackoverflow.com/questions/46933838/filtering-elements -of-AN-陣列與元素-的-另一個陣列式-perl的-6) –