如何将Perl5/PCRE转换为Perl 6正则表达式?

cat*_*cat 8 regex pcre perl6

只是为了得到这一点的方式,我使用index,substr或类似的,因为他们是我的特殊情况下,显而易见的解决办法,但我正在做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
Run Code Online (Sandbox Code Playgroud)

显然,由于多种原因,在Perl 6中不起作用.

基于上述原因,我希望在Perl 6使用此这里就是我试图要翻译成的基础上,CTRL-F荷兰国际集团的perl6正则表达式文档non capturingnegative lookahead:

[ \/ <!before .*> \/ <!after .*> || .? ]*
Run Code Online (Sandbox Code Playgroud)

细分(我想?):

[       # 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
Run Code Online (Sandbox Code Playgroud)

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

我无法为Perl 6 找到相当于http://regex101.com的东西,所以玩它并不像Perl 5那么容易.

我如何将其翻译为Perl 6?

Chr*_*oms 8

简短的回答

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

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

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

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

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


完整答案

如果我理解正确,你只是想匹配一个不包含正斜杠的字符串.在这种情况下,只需使用负字符类.

字符类包含ab将被这样写入:<[ab]>

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

/因此,包含任何其他内容的字符类将被写入:<-[ / ]>以及用于确保字符串中的字符不包含正斜杠的正则表达式/^ <-[ / ]>* $/.

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

say "Match" if "abc/" ~~ /^ <-[ / ]>* $/; # Doesn't match
say "Match" if "abcd" ~~ /^ <-[ / ]>* $/; # Matches
Run Code Online (Sandbox Code Playgroud)

仅检查排除一个字符的首选方法是使用该index功能.但是,如果要排除多个字符,只需使用负字符类以及您不希望在字符串中找到的所有字符.


Luc*_*ski 7

您的原始正则表达式到Perl 6语法的字面翻译^(?:(?!\/).)*$是:

^ [ <!before \/> . ]* $
Run Code Online (Sandbox Code Playgroud)

这对于直接翻译来说非常简单.

  • 替换(?:... )[......]
  • 替换(?!... )<!before......>
  • x默认情况下假设修饰符

在这个例子中,其他一切都保持不变.

我用简单的方法对它进行了测试:

say "Match" if "ab/c" ~~ /^ [ <!before \/> . ]* $/; # doesn't match
say "Match" if "abc"  ~~ /^ [ <!before \/> . ]* $/; # Match
Run Code Online (Sandbox Code Playgroud)

  • 略微可读,避免"倾斜牙签综合症":'^ [<!before'/'>.]*$` (3认同)