Regex 使用正则表达式在perl中打印字母表及其出现处
实现一种使用重复字符计数执行字符串压缩的方法。例如,AABCCCAAAAAA将变成a2b1c5a7。将字符串解压缩为原始字符串 我尝试了下面的代码,但寻找一些单行正则表达式解决方案-Regex 使用正则表达式在perl中打印字母表及其出现处,regex,perl,Regex,Perl,实现一种使用重复字符计数执行字符串压缩的方法。例如,AABCCCAAAAAA将变成a2b1c5a7。将字符串解压缩为原始字符串 我尝试了下面的代码,但寻找一些单行正则表达式解决方案- sub print_word{ my $s=shift; my @a=split(//, $s); my $c=1; my $r=''; my $t=$a[0]; for( my $i=1; $i<=$#a; $i++) { if($t eq $a[$i])
sub print_word{
my $s=shift;
my @a=split(//, $s);
my $c=1;
my $r='';
my $t=$a[0];
for( my $i=1; $i<=$#a; $i++) {
if($t eq $a[$i]) {
$c++;
}else{
$r.=$t."$c";
$t=$a[$i];
$c=1;
}
}
$r.=$t."$c";
return $r;
}
print print_word('aabcccccaaaaaaa') . "\n";
sub-print\u-word{
我的$s=班次;
my@a=拆分(//,$s);
我的$c=1;
我的$r='';
my$t=$a[0];
对于(my$i=1;$iOK),这里的诀窍是——将反向引用与字符串匹配
my $string = 'aabcccccaaaaaaa';
$string =~ s/((\w)\2*)/ "$2". length ($1) /eg;
print $string;
这使得:
a2b1c5a7
我们“捕获”一个单词字符(\w
),并使用\2*
来表示零个或多个字符(由于第一个字母,因此使其“多出一个”)
然后我们将其封装在另一个捕获组中,这意味着我们将\2
或$2
作为单个字母,将\1
或$1
作为同一字母的子字符串
我们打印$2
,然后-因为我们在正则表达式上设置了e
标志-它计算长度($1)
,并插入它
为了扩展我所说的关于效率的内容,我们需要使用代码分析器
使用类似于Devel::NYTProf
:
perl -d:NYTProf script.pl
nytprofhtml --open
您编写的代码:
我的例子
现在,这里有一些规模问题-我的意思是,如果您反复运行,您可能会发现正则表达式解决方案开始“获胜”。使用正则表达式会有很大的开销,某些正则表达式可能非常“昂贵”。例如,请参阅:
尝试相同的测试-例如-在循环中运行这两个100000次,数字开始趋于平衡
地雷:
你的:
但我还是建议——在确定需要之前,不要担心性能。在那之前,选择最容易阅读和理解的内容
在回答另一个问题之前,我不确定结果会是什么,这就是为什么“小心正则表达式”在我脑海中占据很高的位置
它们看起来很整洁,也很聪明,但有时它们有点太聪明了。但在这种情况下,这似乎并不适用。正则表达式引擎有一个开销,但一旦启动,它就会“工作”并运行得很好
计算正则表达式“有多聪明”的一个有用技巧是您可以使用re'debug';
在我的示例中,这打印:
Compiling REx "((\w)\2*)"
Final program:
1: OPEN1 (3)
3: OPEN2 (5)
5: POSIXD[\w] (6)
6: CLOSE2 (8)
8: CURLYX[2] {0,32767} (13)
10: REF2 (12)
12: WHILEM[1/1] (0)
13: NOTHING (14)
14: CLOSE1 (16)
16: END (0)
stclass POSIXD[\w] minlen 1
Matching REx "((\w)\2*)" against "aabcccccaaaaaaa"
Matching stclass POSIXD[\w] against "aabcccccaaaaaaa" (15 bytes)
0 <> <aabcccccaa> | 1:OPEN1(3)
0 <> <aabcccccaa> | 3:OPEN2(5)
0 <> <aabcccccaa> | 5:POSIXD[\w](6)
1 <a> <abcccccaaa> | 6:CLOSE2(8)
1 <a> <abcccccaaa> | 8:CURLYX[2] {0,32767}(13)
1 <a> <abcccccaaa> | 12: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
1 <a> <abcccccaaa> | 10: REF2: "a"(12)
2 <aa> <bcccccaaaa> | 12: WHILEM[1/1](0)
whilem: matched 1 out of 0..32767
2 <aa> <bcccccaaaa> | 10: REF2: "a"(12)
failed...
whilem: failed, trying continuation...
2 <aa> <bcccccaaaa> | 13: NOTHING(14)
2 <aa> <bcccccaaaa> | 14: CLOSE1(16)
2 <aa> <bcccccaaaa> | 16: END(0)
Match successful!
Matching REx "((\w)\2*)" against "bcccccaaaaaaa"
Matching stclass POSIXD[\w] against "bcccccaaaaaaa" (13 bytes)
2 <aa> <bcccccaaaa> | 1:OPEN1(3)
2 <aa> <bcccccaaaa> | 3:OPEN2(5)
2 <aa> <bcccccaaaa> | 5:POSIXD[\w](6)
3 <aab> <cccccaaaaa> | 6:CLOSE2(8)
3 <aab> <cccccaaaaa> | 8:CURLYX[2] {0,32767}(13)
3 <aab> <cccccaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
3 <aab> <cccccaaaaa> | 10: REF2: "b"(12)
failed...
whilem: failed, trying continuation...
3 <aab> <cccccaaaaa> | 13: NOTHING(14)
3 <aab> <cccccaaaaa> | 14: CLOSE1(16)
3 <aab> <cccccaaaaa> | 16: END(0)
Match successful!
Matching REx "((\w)\2*)" against "cccccaaaaaaa"
Matching stclass POSIXD[\w] against "cccccaaaaaaa" (12 bytes)
3 <aab> <cccccaaaaa> | 1:OPEN1(3)
3 <aab> <cccccaaaaa> | 3:OPEN2(5)
3 <aab> <cccccaaaaa> | 5:POSIXD[\w](6)
4 <aabc> <ccccaaaaaa> | 6:CLOSE2(8)
4 <aabc> <ccccaaaaaa> | 8:CURLYX[2] {0,32767}(13)
4 <aabc> <ccccaaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
4 <aabc> <ccccaaaaaa> | 10: REF2: "c"(12)
5 <aabcc> <cccaaaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 1 out of 0..32767
5 <aabcc> <cccaaaaaaa> | 10: REF2: "c"(12)
6 <abccc> <ccaaaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 2 out of 0..32767
6 <abccc> <ccaaaaaaa> | 10: REF2: "c"(12)
7 <bcccc> <caaaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 3 out of 0..32767
7 <bcccc> <caaaaaaa> | 10: REF2: "c"(12)
8 <ccccc> <aaaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 4 out of 0..32767
8 <ccccc> <aaaaaaa> | 10: REF2: "c"(12)
failed...
whilem: failed, trying continuation...
8 <ccccc> <aaaaaaa> | 13: NOTHING(14)
8 <ccccc> <aaaaaaa> | 14: CLOSE1(16)
8 <ccccc> <aaaaaaa> | 16: END(0)
Match successful!
Matching REx "((\w)\2*)" against "aaaaaaa"
Matching stclass POSIXD[\w] against "aaaaaaa" (7 bytes)
8 <ccccc> <aaaaaaa> | 1:OPEN1(3)
8 <ccccc> <aaaaaaa> | 3:OPEN2(5)
8 <ccccc> <aaaaaaa> | 5:POSIXD[\w](6)
9 <ccccca> <aaaaaa> | 6:CLOSE2(8)
9 <ccccca> <aaaaaa> | 8:CURLYX[2] {0,32767}(13)
9 <ccccca> <aaaaaa> | 12: WHILEM[1/1](0)
whilem: matched 0 out of 0..32767
9 <ccccca> <aaaaaa> | 10: REF2: "a"(12)
10 <cccccaa> <aaaaa> | 12: WHILEM[1/1](0)
whilem: matched 1 out of 0..32767
10 <cccccaa> <aaaaa> | 10: REF2: "a"(12)
11 <cccccaaa> <aaaa> | 12: WHILEM[1/1](0)
whilem: matched 2 out of 0..32767
11 <cccccaaa> <aaaa> | 10: REF2: "a"(12)
12 <cccccaaaa> <aaa> | 12: WHILEM[1/1](0)
whilem: matched 3 out of 0..32767
12 <cccccaaaa> <aaa> | 10: REF2: "a"(12)
13 <cccccaaaaa> <aa> | 12: WHILEM[1/1](0)
whilem: matched 4 out of 0..32767
13 <cccccaaaaa> <aa> | 10: REF2: "a"(12)
14 <cccccaaaaaa> <a> | 12: WHILEM[1/1](0)
whilem: matched 5 out of 0..32767
14 <cccccaaaaaa> <a> | 10: REF2: "a"(12)
15 <cccccaaaaaaa> <> | 12: WHILEM[1/1](0)
whilem: matched 6 out of 0..32767
15 <cccccaaaaaaa> <> | 10: REF2: "a"(12)
failed...
whilem: failed, trying continuation...
15 <cccccaaaaaaa> <> | 13: NOTHING(14)
15 <cccccaaaaaaa> <> | 14: CLOSE1(16)
15 <cccccaaaaaaa> <> | 16: END(0)
Match successful!
Matching REx "((\w)\2*)" against ""
Regex match can't succeed, so not even tried
Freeing REx: "((\w)\2*)"
编译REx“((\w)\2*)”
最终课程:
1:OPEN1(3)
3:OPEN2(5)
5:POSIXD[\w](6)
6:2(8)
8:CURLYX[2]{032767}(13)
10:参考文献2(12)
12:WHILEM[1/1](0)
13:无(14)
14:1(16)
16:完(0)
stclass POSIXD[\w]minlen 1
将REx“(\w)\2*)”与“aabcccaaaaaa”匹配
将stclass POSIXD[\w]与“aabcccaaaaaa”(15字节)匹配
0 | 1:OPEN1(3)
0 | 3:OPEN2(5)
0 | 5:POSIXD[\w](6)
1 | 6:关闭2(8)
1 | 8:CURLYX[2]{032767}(13)
1 | 12:WHILEM[1/1](0)
whilem:匹配0中的0..32767
1 | 10:参考文献2:“a”(12)
2 | 12:WHILEM[1/1](0)
whilem:匹配0中的1..32767
2 | 10:参考文献2:“a”(12)
失败。。。
whilem:失败,正在尝试继续。。。
2 | 13:无(14)
2 | 14:CLOSE1(16)
2 | 16:结束(0)
比赛成功!
将REx“(\w)\2*)”与“BCCCAAAAA”匹配
将stclass POSIXD[\w]与“bcccaaaaaa”(13字节)匹配
2 | 1:OPEN1(3)
2 | 3:OPEN2(5)
2 | 5:POSIXD[\w](6)
3 | 6:CLOSE2(8)
3 | 8:CURLYX[2]{032767}(13)
3 | 12:WHILEM[1/1](0)
whilem:匹配0中的0..32767
3 | 10:参考文献2:“b”(12)
失败。。。
whilem:失败,正在尝试继续。。。
3 | 13:无(14)
3 | 14:CLOSE1(16)
3 | 16:结束(0)
比赛成功!
将REx“(\w)\2*)”与“CCCCC AAAAA”匹配
将stclass POSIXD[\w]与“CCCCC AAAAAAAA”(12字节)匹配
3 | 1:OPEN1(3)
3 | 3:OPEN2(5)
3 | 5:POSIXD[\w](6)
4 | 6:CLOSE2(8)
4 | 8:CURLYX[2]{032767}(13)
4 | 12:WHILEM[1/1](0)
whilem:匹配0中的0..32767
4 | 10:参考文献2:“c”(12)
5 | 12:WHILEM[1/1](0)
whilem:匹配0中的1..32767
5 | 10:参考文献2:“c”(12)
6 | 12:WHILEM[1/1](0)
whilem:匹配0中的2..32767
6 | 10:参考文献2:“c”(12)
7 | 12:WHILEM[1/1](0)
whilem:匹配0中的3..32767
7 | 10:参考文献2:“c”(12)
8 | 12:WHILEM[1/1](0)
whilem:匹配0中的4..32767
8 | 10:参考文献2:“c”(12)
失败。。。
whilem:失败,正在尝试继续。。。
8 | 13:无(14)
8 | 14:CLOSE1(16)
8 | 16:结束(0)
比赛成功!
将REx“(\w)\2*)”与“AAAAA”匹配
将stclass POSIXD[\w]与“aaaaaaa”(7字节)匹配
8 | 1:OPEN1(3)
8 | 3:OPEN2(5)
8 | 5:POSIXD[\w](6)
9 | 6:CLOSE2(8)
9 | 8:CURLYX[2]{032767}(13)
9 | 12:WHILEM[1/1](0)
whilem:匹配0中的0..32767
9 | 10:参考文献2:“a”(12)
10 | 12:WHILEM[1/1](0)
whilem:匹配0中的1..32767
10 | 10:参考文献2:“a”(12)
11 | 12:
use strict;
use warnings;
use 5.010;
my $s = 'aabcccccaaaaaaa';
say $s;
(my $encoded = $s) =~ s/(([a-z])\g2*)/$2.length $1/egi;
say $encoded;
(my $decoded = $encoded) =~ s/([a-z])(\d+)/$1 x $2/egi;
say $decoded;
say $s eq $decoded ? 'Match okay' : 'Round trip failed';
aabcccccaaaaaaa
a2b1c5a7
aabcccccaaaaaaa
Match okay