2013-05-21 51 views
8
string1 = "AAABBBBBCCCCCDDDDD" 
string2 = "AEABBBBBCCECCDDDDD" 

出力を比較します。ミスマッチ(この場合はE)がEを囲むHTMLタグで置き換えられます。perlの2つの文字列とハイライト不一致文字

A**E**ABBBBBCC**E**CCDDDDD 

私がこれまでに試したことは、XOR、diff、substrです。まず、指標を見つけてそれらの指標をパターンに置き換える必要があります。

+2

サイズです2つの弦のうち、常に同じですか? – Bill

+0

私はstring2と同じサイズの部分文字列を比較しています。基本的にはそうであると仮定します。 – Jabda

+0

出力は差異を強調表示する2番目の文字列です – Jabda

答えて

7
use strict; 
use warnings; 
my $string1 = 'AAABBBBBCCCCCDDDDD'; 
my $string2 = 'AEABBBBBCCECCDDDDD'; 
my $result = ''; 
for(0 .. length($string1)) { 
    my $char = substr($string2, $_, 1); 
    if($char ne substr($string1, $_, 1)) { 
     $result .= "**$char**"; 
    } else { 
     $result .= $char; 
    } 
} 
print $result; 

プリントややテスト済みA**E**ABBBBBCC**E**CCDDDDD

。エラーが含まれることがあります。

+1

非常に高いパフォーマンスが必要な場合(文字列が非常に長い場合など)、これを行う方法は他にもあります。 – mzedeler

+0

文字列は長くはありませんが、文字列が多数あります。つまり多くの比較 – Jabda

+1

パフォーマンスの問題が発生した場合は、これを最初に試して、新しい質問を投稿してください。各文字列は他の文字列と何度も何度も比較されますか? – mzedeler

2

これを実現するには、いくつかの方法があります。以下はこれを解決するための方法です。

my $str1="ABCDEA"; 
my $str2="AECDEB"; 
my @old1=split("",$str1); 
my @old2=split("",$str2); 

my @new; 

for my $i (0..$#old1) { 
     if ($old1[$i] eq $old2[$i]) { 
       push (@new, $old2[$i]); 
     } 
     else 
     { 
       my $elem = "**".$old2[$i]."**"; 
       push (@new , $elem); 
     } 
} 
print @new; 

出力である:

A**E**CDE**B** 
+0

OP2は、出力が文字列2である必要があります(実際にはstring1 ... string2と同じ長さの文字を出力します) –

4
use warnings; 
use strict; 
my ($s1, $s2, $o1, $o2) = ("AAABBBBBCCCCCDDDDD", "AEABBBBBCCECCDDDDD"); 
my @s1 = split(//, $s1); 
my @s2 = split(//, $s2); 
my $eq_state = 1; 
while (@s1 and @s2) { 
    if (($s1[0] eq $s2[0]) != $eq_state) { 
     $o1 .= (!$eq_state) ? "</b>" : "<b>"; 
     $o2 .= (!$eq_state) ? "</b>" : "<b>"; 
    } 
    $eq_state = $s1[0] eq $s2[0]; 
    $o1.=shift @s1; 
    $o2.=shift @s2; 
} 
print "$o1\n$o2\n"; 

出力

A<b>A</b>ABBBBBCC<b>C</b>CCDDDDD 
A<b>E</b>ABBBBBCC<b>E</b>CCDDDDD 

のみ第2ストリングプリントアウト単純いずれか

use warnings; 
use strict; 
my ($s1, $s2, $was_eq) = ("AAABBBBBCCCCCDDDDD", "AEABBBBBCCECCDDDDD", 1); 
my @s1 = split(//, $s1); 
my @s2 = split(//, $s2); 
for my $idx (0 .. @s2 -1) { 
    my $is_eq = $s1[$idx] eq $s2[$idx]; 
    print $is_eq ? "</b>" : "<b>" if ($was_eq != $is_eq); 
    $was_eq = $is_eq; 
    print $s2[$idx]; 
} 

</b>A<b>E</b>ABBBBBCC<b>E</b>CCDDDDD 
+0

+1は実際にstring2を反復処理します。 string1 –

3

Outoutこれは、大規模な文字列のために、メモリ集約かもしれません。

use strict; 
use warnings; 

my $a = "aabbcc"; 
my $b = "aabdcc"; 

my @a = split //, $a; 
my @b = split //, $b; 

my $new_b = ''; 

for(my $i = 0; $i < scalar(@a); $i++) { 
    $new_b .= $a[$i] eq $b[$i] ? $b[$i] : "**$b[$i]**"; 
} 

OUTPUT:

$ test.pl 
new_b: aab**d**cc 
+0

OPは出力が文字列2でなければならないと述べているので、string2を繰り返し処理する必要があります(あなたの場合、string1 ... string2と同じ長さの文字を出力できます) –

9
my @x = split '', "AAABBBBBCCCCCDDDDD"; 
my @y = split '', "AEABBBBBCCECCDDDDD"; 

my $result = join '', 
      map { $x[$_] eq $y[$_] ? $y[$_] : "**$y[$_]**" } 
      0 .. $#y; 
+0

+ string2を反復する) –

2

列を整列し、ビット単位の文字列演算子 "^" を使用して:

my $a = "aabbccP"; 
my $b = "aabdccEE"; 
$_ = $a^$b; 
s/./ord $& ? "^" : " "/ge; 
print "$_\n" for $a, $b, $_; 

が与える:

aabbccP 
aabdccEE 
^^^ 
関連する問題