Regex 使用正则表达式在perl中打印字母表及其出现处

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])

实现一种使用重复字符计数执行字符串压缩的方法。例如,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]) {
           $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