我怎样才能把这个Perl5/PCRE翻译成Perl 6正则表达式



只是为了解决这个问题,我会使用 indexsubstr 或类似的东西,因为它们是我特定情况的明显解决方案,但我正在做一个grammar,所以我只能使用 regex . :(

话虽如此,关于将Perl5/PCRE正则表达式转换为Perl6正则表达式的建议无论如何都是很好的SO内容,因为Perl 6越来越受欢迎,并且它的正则表达式引擎非常不同。


这是一个正则表达式,仅匹配不包含任何给定字符列表的字符串。
(在这里试试。

^(?:(?!/).)*$
^            # assert position at start of string
(?:          # begin a noncapturing group 
   (?!       # negative lookahead: following regex must not match the string
      /     # literal forward slash
    )        # end negative lookahead
    .        # any character, once
 )*          # the previous noncapturing group, 0..Inf times
 $           # assert position at end of string
显然,由于

多种原因,在 Perl 6 中不起作用。

出于上述原因,我想在 Perl 6 中使用它。以下是我尝试将其翻译的内容,基于 CTRL-F 的 perl6 正则表达式文档,用于non capturingnegative lookahead

[ / <!before .*> / <!after .*> || .? ]*

和细分(我认为?

[       # begin a noncapturing group which apparently look like a charclass in p6
/      # a literal forward slash  
<!before .*> # negative lookahead for the immediately preceding regex (literal /)
/      # a literal /
<!after .*>  # negative lookbehind for the immediately preceding regex
|| .?   # force this to be a noncapturing group, not a charclass
]*      # end noncapturing group and allow it to match 0..Inf times

我像my regex not-in { ... }一样实现它,然后像/^<not-in>$/一样使用它。但是,它为每个字符串返回Nil,这意味着它无法正常工作。

我一直无法找到与 Perl 6 http://regex101.com 相当的,所以使用它并不像使用 Perl 5 那么容易。

我如何将其转换为 Perl 6?

简答

正则表达式,用于仅匹配缺少正斜杠的字符串:/^ <-[ / ]>* $/

/正则表达式的开头
^字符串的开头

<-[打开否定字符类(没有-,这将是一个普通的字符类)
类不匹配的/字符
]> 接近角色类

*此类的零个或多个"副本"
$字符串的结尾
正则表达式的/结尾

默认情况下,Perl 6 正则表达式中的空格将被忽略。

<小时 />

完整答案

如果我理解正确,您只是在尝试匹配不包含正斜杠的字符串。在这种情况下,只需使用负字符类。

包含ab的字符类将编写如下:<[ab]>

包含除ab之外的任何内容的字符类将编写如下:<-[ab]>

包含除/之外的任何内容的字符类将编写为:<-[ / ]>和正则表达式,以确保字符串中不包含正斜杠的字符将被/^ <-[ / ]>* $/

当字符串缺少正斜杠时,此代码匹配,

当字符串包含正斜杠时不匹配时,此代码匹配:

say "Match" if "abc/" ~~ /^ <-[ / ]>* $/; # Doesn't match
say "Match" if "abcd" ~~ /^ <-[ / ]>* $/; # Matches
<小时 />

仅检查排除一个字符的首选方法是使用 index 函数。但是,如果要排除多个字符,只需将负字符类与不想在字符串中找到的所有字符一起使用即可。

^(?:(?!/).)*$ Perl 6 语法的原始正则表达式的直译是:

^ [ <!before /> . ]* $

对于直接翻译来说,这很简单。

  • 更换(?:...)[...]
  • 更换(?!...)<!before...>
  • 默认采用 x 修饰符

在此示例中,其他所有内容保持不变。

我已经用一个简单的测试了它:

say "Match" if "ab/c" ~~ /^ [ <!before /> . ]* $/; # doesn't match
say "Match" if "abc"  ~~ /^ [ <!before /> . ]* $/; # Match

只是为了解决这个问题

您的问题从以下方面开始:

只是为了解决这个问题,我会使用 index、substr 或类似的东西,因为它们是我特定情况的明显解决方案,但我正在制作语法,所以我只能使用 regex。 :(

迂腐,你可以这样做。事实上,你可以在Perl正则表达式中嵌入任意代码。

<小时 />

一个典型的 Perl 6 示例:

/ (d**1..3) <?{ $/ < 256 }> / # match an octet

d**1..3位匹配 1 到 3 个十进制数字。该位周围的(...)括号告诉 Perl 6 将匹配项存储在特殊变量 $/中。

<?{ ... }>位是代码断言。如果代码返回 true,则正则表达式将继续。否则,它将回溯或失败。

<小时 />

在正则表达式中使用index等(在这种情况下,我选择了substr-eq)很麻烦,而且可能很疯狂。但这是可行的:

say "a/c" ~~ / a <?{ $/.orig.substr-eq: '/', $/.to }> . c /;
say "abc" ~~ / a <?{ $/.orig.substr-eq: '/', $/.to }> . c /

显示:

「a/c」
Nil

(在 Match 对象上调用.orig将返回曾经或正在匹配的原始字符串。调用 .to 将返回原始字符串中的索引,该索引与匹配项达到或到目前为止为止为止; "abc" ~~ / a { say $/.orig, $/.to } bc /显示abc1 .)

最新更新