使用正则表达式在perl中打印出它们出现的字母

时间:2015-07-09 13:28:32

标签: regex perl

使用重复字符计数实现一个执行字符串压缩的方法。例如,aabcccccaaaaaaa将成为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";

请在一行中使用正则表达式提供一些内容。

2 个答案:

答案 0 :(得分:6)

好的,这里的诀窍是 - 将引用与字符串匹配;

my $string = 'aabcccccaaaaaaa';

$string =~ s/((\w)\2*)/ "$2". length ($1) /eg;
print $string;

这给出了:

a2b1c5a7

我们捕获&#39;一个单词字符(\w),我们使用\2*来表示零或更多(因此,由于第一个字母而使其更多一个&#39;)。

然后我们将 封装在另一个捕获组中,这意味着我们将\2$2作为我们的单个字母,\1或{{1作为同一个字母的子字符串。

我们打印$1然后 - 因为我们在正则表达式上设置了$2标志 - 它评估e并插入它。

为了扩展我所说的效率 - 我们需要转到代码分析器。

使用length ( $1 )

之类的内容
Devel::NYTProf

您编写的代码:

Your loop

我的例子

My Example

现在,这里有比例问题 - 我的意思是,如果你反复运行,你可能会发现正则表达式解决方案开始了#34; win&#34;。根本没有使用正则表达式的开销,某些正则表达式可能非常昂贵&#39;。例如,请参阅:http://blog.codinghorror.com/regex-performance/

尝试相同的测试 - 例如 - 在循环中运行100,000次,数字开始均匀。

矿:

Regex x 100,000

此致:

Yours x 100,000

但是我仍然建议 - 在您确定需要之前不要担心性能问题。在那之前,请阅读最容易阅读和理解的内容。

我不确定直到我针对另一个问题运行结果catastrophic backtracking,这就是为什么要注意正则表达式&#39;在我心中很高兴。

他们看起来很整洁,他们很聪明,但有时他们有点聪明。但在这种情况下,这似乎并不适用。正则表达式引擎有一个开销,但一旦它开始工作&#39;而且跑得很好。

找出“聪明”的有用技巧之一。正则表达式是perl -d:NYTProf script.pl nytprofhtml --open

以我的例子,这打印:

use re 'debug';

你可以看到,在这个例子中,它实际上做了很多工作。但是因为它不需要在任何时候回溯以匹配你的字符串,所以它并不真正浪费任何努力。

答案 1 :(得分:2)

如果您使用/e修饰符替换表达式,这相当简单。这允许您将Perl表达式放在s///运算符的替换部分而不是简单的字符串

这是一个演示

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