【问题标题】:Can I modify a literal regex in Perl 6?我可以在 Perl 6 中修改文字正则表达式吗?
【发布时间】:2017-10-28 07:00:50
【问题描述】:

假设我们有一个规则的屈折模式,它不能被分割成段。例如。它可以是中缀(在单词中添加一些字母)或元音变化('ablaut')。考虑一个来自德语的例子。

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

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

所有三个德语单词都通过将它们的第二个字母“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

【问题讨论】:

  • 你应该只在让它进入工作状态并且确定你的代码不够快之后进行优化。
  • @BradGilbert,默认情况下使用这种优化有哪些可能的缺点(通常,我使用数百个搜索键和巨大的文本语料库,所以如果没有这种优化,它真的很慢)?除了代码不太灵活和不太优雅。

标签: raku


【解决方案1】:

你不能。

正则表达式是 Perl 6 中的代码对象。所以您的问题基本上是“我可以在编写子例程或方法后修改它们吗?”。传统代码对象和正则表达式的答案是一样的:不,首先写你想要的。

也就是说,您的用例实际上并不需要 EVAL。当您在正则表达式中使用数组变量时,它会被内插为替代分支列表,因此您只需编写:

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

正则表达式$search 变成了一个闭包,所以如果你修改@words,你也会改变$search 匹配的内容。

此特定示例的另一种方法是使用:ignoremark 修饰符,这使得a 也匹配ä(尽管还有许多其他形式,例如āǎ。)

【讨论】:

  • 感谢您的澄清!至于我使用EVAL 而不是/@words/,问题是对于真实数据,我的@words 搜索数组通常包含数百个键。因此,如果我不使用EVAL 对它们进行“预编译”,程序就会变得非常慢。关于这个问题我已经问了几个问题,所以如果有更好的解决方案,请告诉我。 ①Regex speedFiltering an array
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
相关资源
最近更新 更多