Perl'deki iki dizeyi nasıl karşılaştırabilirim?


178

Perl'deki iki dizeyi nasıl karşılaştırabilirim?

Perl öğreniyorum, bu temel soru burada StackOverflow üzerinde baktı ve iyi bir cevap bu yüzden soracağımı düşündüm vardı vardı.


3
Önce Perl ile birlikte gelen mükemmel belgelere başvurmalısınız.
Sinan Ünür

5
Learning Perl (birlikte yazdığım) gibi bir kitaba göz atmak isteyebilirsiniz . Bu soruya iyi cevaplar yoktu çünkü çok basit. Bir eğitim, temel bilgileri hızlı bir şekilde almanıza yardımcı olacaktır.
brian d foy

Yanıtlar:


184

Bkz . Perldoc perlop . Kullanım lt, gt, eq, ne, ve cmpdize karşılaştırmaları için uygun olarak:

eqSol bağımsız değişken, sağ bağımsız değişkene dize olarak eşitse, ikili değer true değerini döndürür.

İkili neSol bağımsız değişken, dize yönünde sağ bağımsız değişkene eşit değilse, true değerini döndürür.

İkili cmp, sol argümanın dize olarak sağ argümandan küçük, eşit veya daha büyük olmasına bağlı olarak -1, 0 veya 1 değerini döndürür.

İkili ~~, argümanları arasında bir akıllı eşleşme yapar. ...

lt, le, ge, gtVe cmpeski kullanımı yerel (ama eğer geçerli yerele tarafından belirtilen harmanlama (sıralama) düzeni kullanmak use locale ':not_characters') yürürlükte. Perllocale bakın . Bunları Unicode ile karıştırmayın, sadece eski ikili kodlamalar ile karıştırın. Standart Unicode :: Collate ve Unicode :: Collate :: Locale modülleri, harmanlama sorunlarına çok daha güçlü çözümler sunar.


9
Sadece bir tane daha, eşit değil.
PJT

4
$ Str1 = ~ "$ str2" nin (/ $ str2 / değil) $ str2'nin $ str1'in bir alt dizesi olup olmadığını kontrol edeceğini belirtmek isteyebilirsiniz.
Daniel C. Sobral

@Daniel index, bir dizenin diğerinin alt dizesi olup olmadığını görmek için kullanın .
Sinan Ünür

3
@Daniel: = ~ "$ str2" ve = ~ / $ str2 / (veya bu konu için sadece = ~ $ str2) arasında çok fazla pratik fark yoktur; index doğru araçtır, ancak herhangi bir nedenle normal ifade kullanmanız gerekiyorsa = ~ / \ Q $ str2 \ E / yapın.
ysth

1
@IliaRostovtsev !=ve neaynı değildir, çünkü !=ve nefarklı oldukları tanımlanmıştır. Bu ne kadar zor ?! Sayısal bir karşılaştırma operatörü olarak, !=her iki işlenenini de sayılara dönüştürür perl -E 'say "equal" if not "a" != "b"'.
Sinan Ünür

137
  • cmp Karşılaştırmak

    'a' cmp 'b' # -1
    'b' cmp 'a' #  1
    'a' cmp 'a' #  0
  • eq Eşittir

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
  • ne Eşit değil

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
  • lt Daha az

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
  • le Küçük veya eşit

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
  • gt Daha büyük

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
  • ge Büyük veya eşit

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

Görmek perldoc perlop fazla bilgi için .

(Bunu biraz basitleştiriyorum ama cmphem boş bir dize hem de sayısal olarak sıfır değeri olan 0bir değer ve hem dize '1'hem de sayısal değer olan bir değer döndürüyorum 1. Bunlar aynı değerlerdir Perl'deki her zaman boolean operatörlerinden alın. Boolean veya sayısal işlemler için döndürme değerlerini gerçekten kullanmalısınız, bu durumda fark gerçekten önemli değildir.)


8
Bu yanıtı daha çok seviyorum. Kısa basit örnekler genellikle banal multage dokümanlar referansından daha yeni başlayanlar için daha yararlıdır.
Zon

@Zon için bu dönüş değerleri hariç eq, gt, ltvb ... doğru değil Bunlar doğru veya yanlış döndürür. Yalnızca cmpbelirli sayısal değerler döndürür.
Sinan Ünür

Perl 6, legbunun yerine cmpgenel karşılaştırmalar için kullanılanlar yerine aynı işleçleri kullanır .
Brad Gilbert

17

Sinan Ünür'ün dize karşılaştırma operatörlerinin kapsamlı listesine ek olarak Perl 5.10 akıllı maç operatörünü ekliyor.

Akıllı eşleştirme operatörü iki öğeyi türlerine göre karşılaştırır. 5.10 davranışı için aşağıdaki tabloya bakın (Bu davranışın 5.10.1'de biraz değiştiğine inanıyorum):

perldoc perlsyn "Ayrıntılı akıllı eşleme" :

Akıllı bir eşleşmenin davranışı, argümanlarının ne tür bir şey olduğuna bağlıdır. Her zaman değişmeli, yani $a ~~ $baynı davranır $b ~~ $a. Davranış aşağıdaki tablo tarafından belirlenir: her iki sırayla uygulanan ilk satır eşleşme davranışını belirler.

  $ a $ b Eşleşme Zımni Eşleşme Kodu
  ====== ===== ===================================
  (aşırı yükleme her şeyi koyar)

  Kod [+] Kod [+] referans eşitliği $ a == $ b   
  Herhangi bir Kod [+] skaler alt gerçek $ b -> ($ a)   

  Hash Hash karma tuşları aynı [sıralama tuşları% $ a] ~~ [sıralama tuşları% $ b]
  Hash Array karma dilim varlığı grep {a $ a -> {$ _}} @ $ b
  Hash Regex karma anahtarı grep grep / $ b /,% $ a tuşları
  Karma Herhangi bir karma giriş varlığı var $ a -> {$ b}

  Dizi Dizi dizileri aynı [*]
  Dizi Regex dizisi grep grep / $ b /, @ $ a
  Dizi Num dizisi grep $ _ == $ b, @ $ a sayısını içerir 
  Dizi Herhangi bir dizi grep $ _ eq $ b, @ $ a dizesi içerir 

  Undef tanımsız! $ A tanımlı
  Herhangi bir Regex kalıbı $ a = ~ / $ b / ile eşleşir 
  Code () Code () sonuçları eşittir $ a -> () eq $ b -> ()
  Herhangi bir Kod () basit kapatma gerçeği $ b -> () # $ a yoksayılıyor
  Num numish [!] Sayısal eşitlik $ a == $ b   
  Herhangi bir Str dize eşitliği $ a eq $ b   
  Herhangi bir Sayısal eşitlik $ a == $ b   

  Herhangi biri Herhangi bir dize eşitliği $ a eq $ b   

+ - bu, prototipi (varsa) "" olmayan bir kod başvurusu olmalıdır
("" prototipi olan alt öğeler aşağıya 'Kod ()' girişi tarafından ele alınır) 
* - yani, her öğe diğerinde aynı dizinin öğesiyle eşleşir
dizi. Dairesel bir referans bulunursa, referansa geri döneriz
eşitlik.   
! - gerçek bir sayı veya sayıya benzeyen bir dize

"Eşleme kodu" gerçek eşleme kodunu temsil etmez, elbette: amaçlanan anlamı açıklamak için sadece orada. Grep'in aksine, akıllı eşleştirme operatörü mümkün olduğunca kısa devre yapar.

Aşırı yükleme ile özel eşleştirme ~~İşleci aşırı yükleyerek bir nesnenin eşleşme şeklini değiştirebilirsiniz . Bu, her zamanki akıllı maç semantiğini ortadan kaldırır. Bkz overload.


Biraz değişmiyor: kökten değişiyor. Basit olmayan herhangi bir şey için akıllı eşleştirme ciddi şekilde bozulur.
brian d foy

1
Dokümanlar bu sırada değiştiği için bağlantı muhtemelen değişmelidir. 5.14.2 güncel
Brad Gilbert

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

Perl, dilde gevşek yazmaya yardımcı olmak için ayrı dize karşılaştırma ve sayısal karşılaştırma işleçlerine sahiptir. Tüm farklı operatörler için perlop okumalısınız .


8

Bu sorunun açık alt metni:

neden sadece ==iki telin aynı olup olmadığını kontrol etmek için kullanmıyorsunuz ?

Perl'in metin ve rakamlar için farklı veri türleri yoktur. Her ikisi de "skaler" tipiyle temsil edilir . Başka bir deyişle, dizeleri bu şekilde kullanırsanız sayıdır .

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

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

print "3"+4
7

Metin ve sayılar dil tarafından farklılaştırılmadığından, ==her iki durum için de doğru olanı yapmak üzere operatörü aşırı yükleyemeyiz . Bu nedenle Perl, eqdeğerleri metin olarak karşılaştırmayı sağlar :

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

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

Kısacası:

  • Perl'in yalnızca metin dizeleri için bir veri türü yok
  • iki işleneni sayı olarak karşılaştırmak için ==veya!=
  • iki işleneni metin olarak karşılaştırmak için eqveyane

Skaler değerleri karşılaştırmak için kullanılabilecek başka birçok işlev ve operatör vardır, ancak bu iki form arasındaki ayrımı bilmek önemli bir ilk adımdır.


Java aynı soruna sahiptir, ancak farklı bir nedenden dolayı (ve farklı sonuçlarla).
Brent Bradburn

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.