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


178

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

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


3
最初に、Perlに付属の優れたドキュメントを参照してください。
SinanÜnür2009

5
Learning Perl(私が共同執筆したもの)などの本を調べてみてください。この質問は非常に基本的なものであるため、この質問に対する適切な回答はありませんでした。チュートリアルは、基本をすばやく習得するのに役立ちます。
ブライアン・ド・フォイ2009

回答:


184

perldoc perlopを参照してください。使用ltgteqne、およびcmp文字列の比較のための適切な:

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

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

Binary cmpは、左の引数が文字列ごとに右の引数よりも小さいか、等しいか、大きいかによって、-1、0、または1を返します。

Binary ~~は引数の間でスマートマッチを行います。...

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


9
もう1つ、等しくないためのne。
PJT 2009

4
$ str1 =〜 "$ str2"(/ $ str2 /ではない)は、$ str2が$ str1の部分文字列であるかどうかをチェックすることを言及する必要があるかもしれません。
ダニエルC.ソブラル

@Daniel indexは、文字列が別の文字列の部分文字列であるかどうかを確認するために使用します。
SinanÜnür2009

3
@Daniel:=〜 "$ str2"と=〜/ $ str2 /の間には実際的な違いはほとんどありません(または、単に=〜$ str2のみ)。indexは適切なツールですが、何らかの理由で正規表現を使用する必要がある場合は、=〜/ \ Q $ str2 \ E /を実行してください。
ys、2009

1
@IliaRostovtsev !=とはneので、同じではありません!=し、ne異なるように定義されています。どれくらい難しいですか。数値比較演算子であるため、!=両方のオペランドを数値に変換しますperl -E 'say "equal" if not "a" != "b"'
SinanÜnür2015年

137
  • 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のブール演算子から取得します。実際にはブール演算または数値演算の戻り値のみを使用する必要があります。この場合、違いは重要ではありません。)


8
私はこの答えがもっと好きです。通常、初心者には短い単純な例のほうが役立ちます。
Zon

@Zonのためにその戻り値を除きeqgtlt等...正しくない彼らは、trueまたはfalseを返します。cmp特定の数値のみを返します。
SinanÜnür2015

Perl 6は、leg代わりにcmp一般的な比較に使用される代わりに使用することを除いて、同じ演算子を使用します。
Brad Gilbert、

17

文字列比較演算子のSinanÜnür包括的なリストに加えて、Perl 5.10はスマート一致演算子を追加します。

スマートマッチオペレーターは、タイプに基づいて2つのアイテムを比較します。5.10の動作については、下のグラフを参照してください(この動作は5.10.1でわずかに変更されていると思います)。

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

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

  $ a $ b一致のタイプ暗黙の一致コード
  ====== ===== ===================== =============
  (オーバーロードはすべてを切り捨てます)

  コード[+]コード[+]参照等価$ a == $ b   
  任意のコード[+]スカラーサブ真理$ b −>($ a)   

  ハッシュハッシュハッシュキーは同一[ソートキー%$ a] ~~ [ソートキー%$ b]
  ハッシュアレイハッシュスライスの存在grep {exists $ a −> {$ _}} @ $ b
  Hash Regexハッシュキーgrep grep / $ b /、キー%$ a
  ハッシュ存在するハッシュエントリ$ a −> {$ b}

  配列配列配列は同一です[*]
  配列正規表現配列grep grep / $ 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文字列の等価$ a eq $ b   
  任意の数値の等式$ a == $ b   

  任意の文字列等価$ a eq $ b   

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

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

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


わずかに変化しているわけではありません。根本的に変化しています。単純ではないものに対するスマートマッチングは、深刻に機能しなくなります。
ブライアン・ド・フォイ2009

1
ドキュメントはその間に変更されているため、リンクはおそらく変更されるはずです。5.14.2 現在
ブラッド・ギルバート

10
print "Matched!\n" if ($str1 eq $str2)

Perlには、言語の緩やかな入力を支援するために、別個の文字列比較演算子と数値比較演算子があります。さまざまな演算子すべてについて、perlopをお読みください


8

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

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

Perlには、テキストと数値の明確なデータ型がありません。これらは、両方の型で表現されている「スカラー」。別の言い方をすると、文字列そのように使用する場合、数値です

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つの形式の違いを知ることは重要な最初のステップです。


Javaにも同じ問題がありますが、理由は異なります(意味も異なります)。
ブレントブラッドバーン

1

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


Perlのドキュメントにリンクする場合は、通常、常に最新バージョンのモジュールにリンクするPermalinksを使用することをお勧めします。search.cpan.org/perldoc/String::Diff search.cpan.org/perldoc?String::Diff p3rl.org/String::Diff metacpan.org/module/String::Diff metacpan.org/pod/String: :Diff Done
Brad Gilbert
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.