只是为了解决这个问题,我会使用 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
显然,由于多种原因,在 Perl 6 中不起作用。
出于上述原因,我想在 Perl 6 中使用它。以下是我尝试将其翻译的内容,基于 CTRL-F 的 perl6 正则表达式文档,用于non capturing
和negative 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 正则表达式中的空格将被忽略。
<小时 />完整答案
如果我理解正确,您只是在尝试匹配不包含正斜杠的字符串。在这种情况下,只需使用负字符类。
包含a
和b
的字符类将编写如下:<[ab]>
包含除a
或b
之外的任何内容的字符类将编写如下:<-[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
.)