195

Perlで2つの文字列を比較するにはどうすればよいですか?

私はPerlを学んでいます。この基本的な質問をStackOverflowで調べてみましたが、良い答えが見つからなかったので、質問したいと思いました。

4

7 に答える 7

202

perldocperlopを参照してください。文字列の比較には、、、、、およびを適切に使用しますltgteqnecmp

eq左の引数が右の引数と文字列的に等しい場合、Binaryはtrueを返します。

ne左の引数が文字列的に右の引数と等しくない場合、Binaryはtrueを返します。

バイナリcmpは、左の引数が右の引数よりも文字列的に小さいか、等しいか、大きいかに応じて、-1、0、または1を返します。

Binary~~は、引数間でスマートマッチを実行します。..。

lt、、、およびレガシー使用ロケール(ではない)が有効な場合は、現在のロケールで指定された照合(ソート)順序を使用leしますgeperllocaleを参照してください。これらをUnicodeと混合しないでください。従来のバイナリ・エンコーディングとのみ混合してください。標準のUnicode::Collat​​eおよびUnicode::Collat​​e :: Localeモジュールは、照合の問題に対してはるかに強力なソリューションを提供します。gtcmpuse locale ':not_characters'

于 2009-07-24T01:34:39.417 に答える
146
  • cmp比較

    'a' cmp 'b' # -1
    'b' cmp 'a' #  1
    'a' cmp 'a' #  0
    
  • eqに等しい

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
    
  • ne等しくない

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
    
  • lt未満

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
    
  • le以下

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
    
  • gt大なり記号

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
    
  • ge以上

    'a' ge  'b' #  0
    'b' ge  'a' #  1
    'a' ge  'a' #  1
    

詳細については、を参照perldoc perlopしてください。

(私はこれを少し単純化していますがcmp、空の文字列であり、の代わりに数値がゼロ0の値であり、文字列'1'と数値の両方である値を返します1。これらは同じ値です。常にPerlのブール演算子から取得します。実際にはブール演算または数値演算の戻り値のみを使用する必要があります。この場合、違いは実際には重要ではありません。)

于 2009-07-24T01:47:24.893 に答える
17

文字列比較演算子のSinanÜnürの包括的なリストに加えて、Perl5.10はスマートマッチ演算子を追加します。

スマートマッチ演算子は、タイプに基づいて2つのアイテムを比較します。5.10の動作については、以下のチャートを参照してください(この動作は、5.10.1でわずかに変化していると思います)。

perldoc perlsyn「スマートマッチングの詳細」

スマートマッチの動作は、その引数がどのような種類のものであるかによって異なります。これは常に可換です。つまり$a ~~ $b、と同じように動作し$b ~~ $aます。動作は次の表によって決定されます。どちらの順序でも適用される最初の行が、一致動作を決定します。

  $ a$b一致のタイプ暗黙の一致コード
  ====== ===== ===================== =============
  (オーバーロードはすべてに勝る)

  コード[+]コード[+]参照の同等性$a== $ b   
  任意のCode[+]スカラーサブトゥルース$b->($ a)   

  ハッシュハッシュハッシュキーは同一[ソートキー%$ a] ~~ [ソートキー%$ b]
  ハッシュ配列ハッシュスライス存在grep{exists$ a-> {$ _}} @ $ b
  ハッシュ正規表現ハッシュキーgrepgrep/ $ b /、キー%$ a
  ハッシュハッシュエントリが存在する場合は$a->{$ b}

  配列配列配列は同一です[*]
  配列正規表現arraygrepgrep / $ b /、@ $ a
  配列Num配列には数値grepが含まれます$_== $ b、@ $ a
  配列任意の配列には文字列grep$_ eq $ b、@$aが含まれます

  undef undefined!defined $ a
  すべての正規表現パターンは$a=〜/ $b/に一致します
  Code()Code()の結果は等しい$ a->()eq $ b->()
  任意のCode()単純閉包真理$ b->()#$aを無視する
  Num numish [!]数値の平等$ a == $ b   
  任意のStr文字列の等式$aeq $ b   
  任意の数値の等式$a== $ b   

  任意の任意の文字列の等式$aeq $ b   

+ −これは、プロトタイプ(存在する場合)が「」ではないコード参照である必要があります
(「」プロトタイプを持つサブは、下の「Code()」エントリによって処理されます)
* −つまり、各要素は他の同じインデックスの要素と一致します
配列。循環参照が見つかった場合は、参照にフォールバックします
平等。   
!−実数、または数字のように見える文字列

もちろん、「一致するコード」は実際の一致するコードを表すものではありません。意図された意味を説明するためだけにあります。grepとは異なり、スマートマッチ演算子は可能な限り短絡します。

~~オーバーロードによるカスタムマッチング演算子 をオーバーロードすることにより、オブジェクトのマッチング方法を変更できます。これは、通常のスマートマッチセマンティクスよりも優れています。を参照してくださいoverload

于 2009-07-24T05:01:59.533 に答える
11

この質問の明らかなサブテキストは次のとおりです。

==2つの文字列が同じかどうかを確認するためだけに使用できないのはなぜですか?

Perlには、テキストと数値の明確なデータ型はありません。どちらも「scalar」タイプで表されます。言い換えれば、文字列をそのまま使用する場合、文字列数値です。

if ( 4 == "4" ) { print "true"; } else { print "false"; }
true

if ( "4" == "4.0" ) { print "true"; } else { print "false"; }
true

print "3"+4
7

テキストと数字は言語によって区別されない==ため、どちらの場合も正しいことを行うために演算子を単純にオーバーロードすることはできません。したがって、Perlはeq値をテキストとして比較することを提供します。

if ( "4" eq "4.0" ) { print "true"; } else { print "false"; }
false

if ( "4.0" eq "4.0" ) { print "true"; } else { print "false"; }
true

要するに:

  • Perlには、テキスト文字列専用のデータ型はありません
  • ==またはを使用!=して、2つのオペランドを数値として比較します
  • eqまたはを使用neして、2つのオペランドをテキストとして比較します

スカラー値を比較するために使用できる関数や演算子は他にもたくさんありますが、これら2つの形式の違いを知ることは重要な最初のステップです。

于 2015-11-18T01:50:14.313 に答える
10
print "Matched!\n" if ($str1 eq $str2)

Perlには、言語での緩い型付けを支援するために、個別の文字列比較演算子と数値比較演算子があります。さまざまな演算子すべてについてperlopを読む必要があります。

于 2009-07-24T01:35:10.383 に答える
1

また、2つの文字列の違いを抽出したい場合は、String::Diffを使用できます。

于 2013-06-19T03:27:02.277 に答える
0

私は、PerlでA>BまたはZ<AAの場合に比較できる解決策を探しに来ました。ここでは何も確実に機能しなかったので、私は独自の解決策を思いつきました。秘訣は、各文字に番号を割り当てることです

例えば

A=1
B=2
C=3 and so on

次に、A> Bの場合に比較するときが来たら、対応する数値を取得し、この場合は1>2で比較します。

ここで動作するperlコード。

# header
use warnings;
use strict;

#create a hash of letters
my %my_hash_lookup;
my $letter_counter=0;
foreach my $letters ('A'..'ZZ')
{
    #print "$letters \n";
    
    $letter_counter++;
    my $key = $letters;
    my $keyValue = $letter_counter;
    $my_hash_lookup{$key}=$keyValue;
}


my $size = keys %my_hash_lookup;
print "hash size: $size ...\n";

#get number value of string letters
        my $my_hash_value1 = $my_hash_lookup{"A"};
        my $my_hash_value2 = $my_hash_lookup{"B"};
        
        if  ( (defined $my_hash_value1) && (defined $my_hash_value2))
        {

            if ($my_hash_value1 == $my_hash_value2)
            {
                #equal
            }
            elsif ($my_hash_value1 > $my_hash_value2)
            {
                #greater than
                
            }
            elsif ($my_hash_value1 < $my_hash_value2)
            {
                #less than
            }
            
        }
于 2021-04-16T04:15:53.110 に答える