【发布时间】:2020-01-06 23:27:32
【问题描述】:
我正在研究homoglyphs module,我必须构建正则表达式,它可以找到对应于 ASCII 等价物的同形文字。
例如,我有一个没有同形文字替代品的字符:
my $f = 'f';
和可以混淆的字符:
my @o = 'o', 'о', 'ο'; # ASCII o, Cyrillic o, Greek omicron
我可以轻松构建正则表达式来检测同形词短语“foo”:
say 'Suspicious!' if $text ~~ / $f @o @o /;
但是如果我不知道在编译时要检测的值,我应该如何编写这样的正则表达式?假设我想检测邮件中包含同形字“现金”字样的网络钓鱼。我可以使用所有替代方案构建序列:
my @lookup = ['c', 'с', 'ϲ', 'ς'], ['a', 'а', 'α'], 's', 'h'; # arbitrary runtime length
现在显然以下解决方案无法将数组元素“解包”到正则表达式中:
/ @lookup / # doing LTM, not searching elements in sequence
我可以通过手动引用每个元素并编写替代项的文本表示来解决此问题,以获得可以作为正则表达式评估的字符串。并使用字符串插值构建令牌:
my $regexp-ish = textualize( @lookup ); # string "[ 'c' | 'с' | 'ϲ' | 'ς' ] [ 'a' | 'а' | 'α' ] 's' 'h'"
my $token = token { <$regexp-ish> }
但这很容易出错。 是否有任何更简洁的解决方案可以从编译时未知的任意数量的元素动态组合正则表达式?
【问题讨论】:
-
顺便说一句 - 我知道我也可以递归地构建它,将每个查找部分嵌套在子令牌中:
my $token1 = token { @lookup[0] }; $token2 = token { <$token1> @lookup[1] };...(当然这是语法错误,只是说明这个想法)。然而,这不会产生“健康”的语法。
标签: raku