perl6 颜色匹配,一些正则表达式插值有效,有些则无效;颜色代码不一致
perl6 Colored match, some regex interpolation works and some don't; color code inconsistent
我有一些长线,我想用我想要的颜色突出显示匹配项。一个函数使用替换,另一个函数使用递归。有些有效,有些无效;我正在寻找一种一致的方法来插入正则表达式。非常感谢!!!
sub colorMatch ($aStr, $aRegex, $aColor) {
my $colorOff = '\e[0m';
my $a =$aStr.subst(/(<{$aRegex}>)/, $aColor ~ "# $/ #" ~ $colorOff, :g);
# not working, $/ not interpolating corresponding matches, all Nil
say $a;
}
colorMatch("a-12-b-3-c-4-def-567", '\d+', '\e[1;31m');
colorMatch("a-12-b-3-c-4-def-567", '<alpha>+', '\e[1;31m');
say "\e[1;31m" ~ " color1 " ~ "\e[0m" ~
"\e[1;36m" ~ " color2 " ~ "\e[0m";
sub colorMatch2 ($aStr, $aRegex, $colorNumber) {
my $colorOff = "\e[0m";
if $aStr.chars > 0 {
my $x1 = ($aStr ~~ m/<{$aRegex}>/);
my $x2 = $x1.prematch;
my $x3 = $x1.Str;
my $x4 = $x1.postmatch;
return ($x2 ~ "\e[1;{$colorNumber}m" ~ $x3 ~ $colorOff)
~ colorMatch2($x4, $aRegex, $colorNumber);
}
}
say colorMatch2("a-12-b-3-c-4-def-567", '\d+', 31); # works, red color
say colorMatch2("a-12-b-3-c-4-def-567", '567', 36); # works, green color
say colorMatch2("a-12-b-3-c-4-def-567", '\w+', 31); # works, red color
say colorMatch2("a-12-b-3-c-4-def-567", '[a..z]+', 31); # fails with [] and ..
say colorMatch2("a-12-b-3-c-4-def-567", "<alpha>+", 31); # fails with <>
Use of Nil in string context
in sub colorMatch at colorMatch.pl line 4
a-\e[1;31m# #\e[0m-b-\e[1;31m# #\e[0m-c-\e[1;31m# #\e[0m-def-\e[1;31m# #\e[0m
# seems to do substitution, but $/ is empty and color not shown;
Use of Nil in string context
in sub colorMatch at colorMatch.pl line 4
\e[1;31m# #\e[0m-12-\e[1;31m# #\e[0m-3-\e[1;31m# #\e[0m-4-\e[1;31m# #\e[0m-567
# seems to do substitution, but $/ is empty and color not shown;
color1 color2 # both colors work and shown as expected,
# color1 red and color 2 green; why inconsistent with above???
a-12-b-3-c-4-def-567 # works, red color
a-12-b-3-c-4-def-567 # works, green color
a-12-b-3-c-4-def-567 # works, red color
No such method 'prematch' for invocant of type 'Bool'
in sub colorMatch2 at colorMatch.pl line 17
in block <unit> at colorMatch.pl line 28
这不是插值问题。字符 类 和范围的语法略有不同。您需要:
'text' ~~ / <[a..z]>+ /
至于关于在 bool 上调用 prematch()
的其他错误,结果是 False
因为在最终递归级别,它不再匹配。在假设匹配之前,您需要检查结果。
最后,对于 "Use of Nil in string context",这是因为您正在使用 Str.subst
,并且与大多数语言中的大多数函数调用一样,参数在函数开始之前计算。您在参数中使用了 $/
,但它尚未设置,因为函数的主体甚至还没有开始执行。 s/match/replacement/
运算符不会遇到这个困难,所以我建议您将代码更改为:
$aStr ~~ s:g/(<$aRegex>)/$aColor# $/ #$colorOff/;
(或者为了更好的可读性:)
$aStr ~~ s:g {(<$aRegex>)} = "$aColor# $/ #$colorOff";
这假设您已经将 $aRegex
变成了正则表达式而不是字符串。另外,由于新代码修改了$aStr
,所以需要将函数签名中的$aStr
改为$aStr is copy
。
谢谢大家的帮助。这是我的修订版。唯一的问题是,由于某种原因我无法弄清楚,替换函数不解释颜色代码,但相同的颜色代码适用于普通 "say" 例程。谢谢!
注意:定义 'my $x = rx/$aRegex/' 然后使用 '/< $x >/' 无法预测;所以我最终使用 /<{$aRegex}>/;
sub colorMatch ($aStr, $aRegex, $aColor) {
my $colorOff = '\e[0m';
my $x = rx/$aRegex/;
my $bStr = $aStr;
$_ = $aStr;
# my $a =$aStr.subst(/(<$x>)/, $aColor ~ "# $/ #" ~ $colorOff, :g);
# $bStr ~~ s:g/(<$x>)/$aColor ~ "# $/ #" ~ $colorOff/;
# s:g/(<{$aRegex}>)/($aColor $/ $colorOff)/;
s:g/(<{$aRegex}>)/($aColor $/ $colorOff)/;
say $_; # for some reason, color codes are not interpreted;
}
colorMatch("a-12-b-3-c-4-def-567", '\d+', '\e[1;31m');
colorMatch("a-12-b-3-c-4-def-567", '<alpha>+', '\e[1;36m');
say "\e[1;31m" ~ " color1 " ~ "\e[0m" ~ "\e[1;36m" ~ " color2 " ~ "\e[0m";
say "a-\e[1;31m 12 \e[0m-b-\e[1;31m 3 \e[0m-c-\e[1;31m 4 \e[0m-def-\e[1;31m 567 \e[0m"; # this works;
say "\e[1;31m a \e[0m-12-\e[1;31m b \e[0m-3-\e[1;31m c \e[0m-4-\e[1;31m def \e[0m-567"; # this works
say "(\e[1;36m a \e[0m)-12-(\e[1;36m b \e[0m)-3-(\e[1;36m c \e[0m)-4-(\e[1;36m def \e[0m)-567"; # works
sub colorMatch2 ($aStr, $aRegex, $colorNumber) {
my $colorOff = "\e[0m";
# my $x = rx/$aRegex/;
# say $x; # /$x/ or /<$x>/ do not all work; prints out "rx/$aRegex/"
if $aStr.chars > 0 {
my $x1 = ($aStr ~~ m/<{$aRegex}>/); # <{$aRegex}> works
my $x2 = $x1 ?? $x1.prematch !! $aStr;
my $x3 = $x1 ?? $x1.Str !! "";
my $x4 = $x1 ?? $x1.postmatch !! "";
return ($x2 ~ "\e[1;{$colorNumber}m" ~ $x3 ~ $colorOff)
~ colorMatch2($x4, $aRegex, $colorNumber);
} else {
return "";
}
}
# colorMatch2 all works now:
say colorMatch2("a-12-b-3-c-4-def-567", '\d+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", '567', 36);
say colorMatch2("a-12-b-3-c-4-def-567", '\w+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", '<[a..z]>+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", "<alpha>+", 31);
结果:
a-(\e[1;31m 12 \e[0m)-b-(\e[1;31m 3 \e[0m)-c-(\e[1;31m 4 \e[0m)-def-(\e[1;31m 567 \e[0m)
(\e[1;36m a \e[0m)-12-(\e[1;36m b \e[0m)-3-(\e[1;36m c \e[0m)-4-(\e[1;36m def \e[0m)-567
color1 color2
a- 12 -b- 3 -c- 4 -def- 567
a -12- b -3- c -4- def -567
( a )-12-( b )-3-( c )-4-( def )-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
您可能还想查看 Terminal::ANSIColor
https://github.com/tadzik/Terminal-ANSIColor/
我怀疑您的代码作为语法和动作也能很好地工作,并且更具可读性。因为您本质上想要 运行 一组正则表达式覆盖一段文本。 https://docs.perl6.org/language/grammar_tutorial
我有一些长线,我想用我想要的颜色突出显示匹配项。一个函数使用替换,另一个函数使用递归。有些有效,有些无效;我正在寻找一种一致的方法来插入正则表达式。非常感谢!!!
sub colorMatch ($aStr, $aRegex, $aColor) {
my $colorOff = '\e[0m';
my $a =$aStr.subst(/(<{$aRegex}>)/, $aColor ~ "# $/ #" ~ $colorOff, :g);
# not working, $/ not interpolating corresponding matches, all Nil
say $a;
}
colorMatch("a-12-b-3-c-4-def-567", '\d+', '\e[1;31m');
colorMatch("a-12-b-3-c-4-def-567", '<alpha>+', '\e[1;31m');
say "\e[1;31m" ~ " color1 " ~ "\e[0m" ~
"\e[1;36m" ~ " color2 " ~ "\e[0m";
sub colorMatch2 ($aStr, $aRegex, $colorNumber) {
my $colorOff = "\e[0m";
if $aStr.chars > 0 {
my $x1 = ($aStr ~~ m/<{$aRegex}>/);
my $x2 = $x1.prematch;
my $x3 = $x1.Str;
my $x4 = $x1.postmatch;
return ($x2 ~ "\e[1;{$colorNumber}m" ~ $x3 ~ $colorOff)
~ colorMatch2($x4, $aRegex, $colorNumber);
}
}
say colorMatch2("a-12-b-3-c-4-def-567", '\d+', 31); # works, red color
say colorMatch2("a-12-b-3-c-4-def-567", '567', 36); # works, green color
say colorMatch2("a-12-b-3-c-4-def-567", '\w+', 31); # works, red color
say colorMatch2("a-12-b-3-c-4-def-567", '[a..z]+', 31); # fails with [] and ..
say colorMatch2("a-12-b-3-c-4-def-567", "<alpha>+", 31); # fails with <>
Use of Nil in string context
in sub colorMatch at colorMatch.pl line 4
a-\e[1;31m# #\e[0m-b-\e[1;31m# #\e[0m-c-\e[1;31m# #\e[0m-def-\e[1;31m# #\e[0m
# seems to do substitution, but $/ is empty and color not shown;
Use of Nil in string context
in sub colorMatch at colorMatch.pl line 4
\e[1;31m# #\e[0m-12-\e[1;31m# #\e[0m-3-\e[1;31m# #\e[0m-4-\e[1;31m# #\e[0m-567
# seems to do substitution, but $/ is empty and color not shown;
color1 color2 # both colors work and shown as expected,
# color1 red and color 2 green; why inconsistent with above???
a-12-b-3-c-4-def-567 # works, red color
a-12-b-3-c-4-def-567 # works, green color
a-12-b-3-c-4-def-567 # works, red color
No such method 'prematch' for invocant of type 'Bool'
in sub colorMatch2 at colorMatch.pl line 17
in block <unit> at colorMatch.pl line 28
这不是插值问题。字符 类 和范围的语法略有不同。您需要:
'text' ~~ / <[a..z]>+ /
至于关于在 bool 上调用 prematch()
的其他错误,结果是 False
因为在最终递归级别,它不再匹配。在假设匹配之前,您需要检查结果。
最后,对于 "Use of Nil in string context",这是因为您正在使用 Str.subst
,并且与大多数语言中的大多数函数调用一样,参数在函数开始之前计算。您在参数中使用了 $/
,但它尚未设置,因为函数的主体甚至还没有开始执行。 s/match/replacement/
运算符不会遇到这个困难,所以我建议您将代码更改为:
$aStr ~~ s:g/(<$aRegex>)/$aColor# $/ #$colorOff/;
(或者为了更好的可读性:)
$aStr ~~ s:g {(<$aRegex>)} = "$aColor# $/ #$colorOff";
这假设您已经将 $aRegex
变成了正则表达式而不是字符串。另外,由于新代码修改了$aStr
,所以需要将函数签名中的$aStr
改为$aStr is copy
。
谢谢大家的帮助。这是我的修订版。唯一的问题是,由于某种原因我无法弄清楚,替换函数不解释颜色代码,但相同的颜色代码适用于普通 "say" 例程。谢谢!
注意:定义 'my $x = rx/$aRegex/' 然后使用 '/< $x >/' 无法预测;所以我最终使用 /<{$aRegex}>/;
sub colorMatch ($aStr, $aRegex, $aColor) {
my $colorOff = '\e[0m';
my $x = rx/$aRegex/;
my $bStr = $aStr;
$_ = $aStr;
# my $a =$aStr.subst(/(<$x>)/, $aColor ~ "# $/ #" ~ $colorOff, :g);
# $bStr ~~ s:g/(<$x>)/$aColor ~ "# $/ #" ~ $colorOff/;
# s:g/(<{$aRegex}>)/($aColor $/ $colorOff)/;
s:g/(<{$aRegex}>)/($aColor $/ $colorOff)/;
say $_; # for some reason, color codes are not interpreted;
}
colorMatch("a-12-b-3-c-4-def-567", '\d+', '\e[1;31m');
colorMatch("a-12-b-3-c-4-def-567", '<alpha>+', '\e[1;36m');
say "\e[1;31m" ~ " color1 " ~ "\e[0m" ~ "\e[1;36m" ~ " color2 " ~ "\e[0m";
say "a-\e[1;31m 12 \e[0m-b-\e[1;31m 3 \e[0m-c-\e[1;31m 4 \e[0m-def-\e[1;31m 567 \e[0m"; # this works;
say "\e[1;31m a \e[0m-12-\e[1;31m b \e[0m-3-\e[1;31m c \e[0m-4-\e[1;31m def \e[0m-567"; # this works
say "(\e[1;36m a \e[0m)-12-(\e[1;36m b \e[0m)-3-(\e[1;36m c \e[0m)-4-(\e[1;36m def \e[0m)-567"; # works
sub colorMatch2 ($aStr, $aRegex, $colorNumber) {
my $colorOff = "\e[0m";
# my $x = rx/$aRegex/;
# say $x; # /$x/ or /<$x>/ do not all work; prints out "rx/$aRegex/"
if $aStr.chars > 0 {
my $x1 = ($aStr ~~ m/<{$aRegex}>/); # <{$aRegex}> works
my $x2 = $x1 ?? $x1.prematch !! $aStr;
my $x3 = $x1 ?? $x1.Str !! "";
my $x4 = $x1 ?? $x1.postmatch !! "";
return ($x2 ~ "\e[1;{$colorNumber}m" ~ $x3 ~ $colorOff)
~ colorMatch2($x4, $aRegex, $colorNumber);
} else {
return "";
}
}
# colorMatch2 all works now:
say colorMatch2("a-12-b-3-c-4-def-567", '\d+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", '567', 36);
say colorMatch2("a-12-b-3-c-4-def-567", '\w+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", '<[a..z]>+', 31);
say colorMatch2("a-12-b-3-c-4-def-567", "<alpha>+", 31);
结果:
a-(\e[1;31m 12 \e[0m)-b-(\e[1;31m 3 \e[0m)-c-(\e[1;31m 4 \e[0m)-def-(\e[1;31m 567 \e[0m)
(\e[1;36m a \e[0m)-12-(\e[1;36m b \e[0m)-3-(\e[1;36m c \e[0m)-4-(\e[1;36m def \e[0m)-567
color1 color2
a- 12 -b- 3 -c- 4 -def- 567
a -12- b -3- c -4- def -567
( a )-12-( b )-3-( c )-4-( def )-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
a-12-b-3-c-4-def-567
您可能还想查看 Terminal::ANSIColor
https://github.com/tadzik/Terminal-ANSIColor/
我怀疑您的代码作为语法和动作也能很好地工作,并且更具可读性。因为您本质上想要 运行 一组正则表达式覆盖一段文本。 https://docs.perl6.org/language/grammar_tutorial