Bagaimana cara membandingkan dua string dalam Perl?

178

Bagaimana cara membandingkan dua string dalam Perl?

Saya belajar Perl, saya punya pertanyaan mendasar mencarinya di sini di StackOverflow dan tidak menemukan jawaban yang baik jadi saya pikir saya akan bertanya.

PJT
sumber
3
Anda harus terlebih dahulu berkonsultasi dengan dokumentasi luar biasa yang disertakan dengan Perl.
Sinan Ünür
5
Anda mungkin ingin membaca buku seperti Learning Perl (yang saya tulis bersama). Tidak ada jawaban yang baik untuk pertanyaan ini karena sangat mendasar. Tutorial akan membantu Anda memahami dasar-dasarnya dengan cepat.
brian d foy

Jawaban:

184

Lihat perlop perldoc . Gunakan lt, gt, eq, ne, dan cmpsesuai untuk perbandingan string:

Biner eqmengembalikan nilai true jika argumen kiri sama dengan argumen kanan.

Biner nemengembalikan true jika argumen kiri adalah stringwise tidak sama dengan argumen yang benar.

Biner cmpmengembalikan -1, 0, atau 1 tergantung pada apakah argumen kiri kurang dari, sama dengan, atau lebih besar dari argumen kanan.

Binary ~~melakukan smartmatch antara argumennya. ...

lt, le, ge, gtDan cmpmenggunakan pemeriksaan (semacam) agar ditentukan oleh lokal saat ini jika penggunaan warisan lokal (tapi tidak use locale ':not_characters') yang berlaku. Lihat perllocale . Jangan mencampur ini dengan Unicode, hanya dengan pengkodean biner lama. Modul standar Unicode :: Collate dan Unicode :: Collate :: Locale menawarkan solusi yang jauh lebih kuat untuk masalah collation.

Sinan Ünür
sumber
9
Hanya satu lagi, ne untuk tidak sama.
PJT
4
Anda mungkin ingin menyebutkan bahwa $ str1 = ~ "$ str2" (bukan / $ str2 /) akan memeriksa apakah $ str2 adalah substring dari $ str1.
Daniel C. Sobral
@Daniel gunakan indexuntuk melihat apakah string adalah substring dari yang lain.
Sinan Ünür
3
@Aniel: tidak ada banyak perbedaan praktis antara = ~ "$ str2" dan = ~ / $ str2 / (atau hanya = ~ $ str2 dalam hal ini); index adalah alat yang tepat, tetapi jika Anda perlu menggunakan regex karena suatu alasan, lakukan = ~ / \ Q $ str2 \ E /.
ysth
1
@IliaRostovtsev !=dan netidak sama, karena !=dan nedidefinisikan berbeda. Seberapa keras itu ?! Menjadi operator perbandingan numerik, !=mengubah kedua operan menjadi angka perl -E 'say "equal" if not "a" != "b"'.
Sinan Ünür
137
  • cmp Membandingkan

    'a' cmp 'b' # -1
    'b' cmp 'a' #  1
    'a' cmp 'a' #  0
  • eq Sama dengan

    'a' eq  'b' #  0
    'b' eq  'a' #  0
    'a' eq  'a' #  1
  • ne Tidak sebanding dengan

    'a' ne  'b' #  1
    'b' ne  'a' #  1
    'a' ne  'a' #  0
  • lt Kurang dari

    'a' lt  'b' #  1
    'b' lt  'a' #  0
    'a' lt  'a' #  0
  • le Kurang dari atau sama dengan

    'a' le  'b' #  1
    'b' le  'a' #  0
    'a' le  'a' #  1
  • gt Lebih besar dari

    'a' gt  'b' #  0
    'b' gt  'a' #  1
    'a' gt  'a' #  0
  • ge Lebih dari atau sama dengan

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

Lihat perldoc perlopuntuk informasi lebih lanjut.

(Saya menyederhanakan ini sedikit tetapi cmpmengembalikan nilai yang merupakan string kosong, dan bukan nilai numerik nol 0, dan nilai yang merupakan string '1'dan nilai numerik 1. Ini adalah nilai yang sama dengan yang Anda inginkan selalu dapatkan dari operator boolean di Perl. Anda seharusnya hanya menggunakan nilai pengembalian untuk operasi boolean atau numerik, dalam hal ini perbedaannya tidak terlalu penting.)

Brad Gilbert
sumber
8
Saya lebih suka jawaban ini. Contoh-contoh sederhana pendek biasanya lebih bermanfaat bagi pemula, daripada hanya rujukan dokumen multi halaman.
Zon
@Zon kecuali bahwa nilai kembali untuk eq, gt, ltdll tidak benar ... Mereka kembali benar atau salah. Hanya cmpmengembalikan nilai numerik tertentu.
Sinan Ünür
Perl 6 menggunakan operator yang sama kecuali ia menggunakan legbukannya cmpyang digunakan untuk perbandingan generik.
Brad Gilbert
17

Selain Sinan Ünür daftar komprehensif operator perbandingan string, Perl 5.10 menambahkan operator pertandingan pintar.

Operator kecocokan pintar membandingkan dua item berdasarkan jenisnya. Lihat grafik di bawah ini untuk perilaku 5.10 (saya percaya perilaku ini sedikit berubah di 5.10.1):

perldoc perlsyn"Pencocokan pintar secara detail" :

Perilaku kecocokan cerdas bergantung pada jenis argumennya. Itu selalu komutatif, yaitu $a ~~ $bberperilaku sama dengan $b ~~ $a. Perilaku ditentukan oleh tabel berikut: baris pertama yang berlaku, dalam urutan apa pun, menentukan perilaku kecocokan.

  $ a $ b Jenis Pencocokan Kode Pencocokan Tersirat
  ====== ===== ===================== =============
  (Overloading mengalahkan segalanya)

  Kode [+] Kode [+] persamaan referensial $ a == $ b   
  Kode Apa pun [+] skalar sub kebenaran $ b -> ($ a)   

  Hash Hash kunci hash identik [kunci sortir% $ a] ~~ [kunci sortir% $ b]
  Keberadaan hash slice Hash Array grep {ada $ a -> {$ _}} @ $ b
  Hash Regex kunci hash grep grep / $ b /, kunci% $ a
  Hash Adanya entri hash ada $ a -> {$ b}

  Array Array array adalah identik [*]
  Array Regex array grep grep / $ b /, @ $ a
  Array Num array berisi angka grep $ _ == $ b, @ $ a 
  Array Setiap array berisi string grep $ _ eq $ b, @ $ a 

  Undefined undefined! Didefinisikan $ a
  Kecocokan pola Regex apa pun $ a = ~ / $ b / 
  Code () Hasil Code () sama dengan $ a -> () eq $ b -> ()
  Kode apa pun () kebenaran penutupan sederhana $ b -> () # abaikan $ a
  Num numish [!] Persamaan numerik $ a == $ b   
  Kesetaraan string Str apa saja $ a eq $ b   
  Kesetaraan angka numerik apa pun $ a == $ b   

  Any Any any string equality $ a eq $ b   

+ - ini harus berupa referensi kode yang prototipenya (jika ada) bukan ""
(subs dengan "" prototipe ditangani oleh entri 'Kode ()' lebih rendah ke bawah) 
* - yaitu, setiap elemen cocok dengan elemen indeks yang sama di lainnya
Himpunan. Jika referensi melingkar ditemukan, kami kembali ke referensi
persamaan.   
! - baik bilangan real, atau string yang terlihat seperti angka

"Kode pencocokan" tidak mewakili kode pencocokan nyata, tentu saja: hanya ada di sana untuk menjelaskan arti yang dimaksud. Tidak seperti grep, operator korek api pintar akan melakukan hubungan pendek kapan pun bisa.

Pencocokan khusus melalui overloading Anda dapat mengubah cara suatu objek dicocokkan dengan overloading ~~operator. Ini mengalahkan semantik pertandingan cerdas yang biasa. Lihat overload.

Chas. Owens
sumber
Itu tidak berubah sedikit: itu berubah secara radikal. Pencocokan pintar untuk apa pun yang tidak sederhana rusak parah.
brian d foy
1
Tautan mungkin harus berubah karena dokumen telah berubah dalam waktu yang bersamaan. 5.14.2 saat ini
Brad Gilbert
10
print "Matched!\n" if ($str1 eq $str2)

Perl memiliki perbandingan string terpisah dan operator perbandingan numerik untuk membantu pengetikan longgar dalam bahasa. Anda harus membaca perlop untuk semua operator yang berbeda.

Matthew Scharley
sumber
8

Subteks yang jelas dari pertanyaan ini adalah:

mengapa Anda tidak bisa hanya menggunakan ==untuk memeriksa apakah dua string sama?

Perl tidak memiliki tipe data yang berbeda untuk teks vs angka. Keduanya diwakili oleh tipe "skalar" . Dengan kata lain, string adalah angka jika Anda menggunakannya .

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

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

print "3"+4
7

Karena teks dan angka tidak dibedakan berdasarkan bahasa, kami tidak bisa begitu saja membebani ==operator untuk melakukan hal yang benar untuk kedua kasus. Oleh karena itu, Perl menyediakan equntuk membandingkan nilai sebagai teks:

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

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

Pendeknya:

  • Perl tidak memiliki tipe data khusus untuk string teks
  • gunakan ==atau !=, untuk membandingkan dua operan sebagai angka
  • gunakan eqatau ne, untuk membandingkan dua operan sebagai teks

Ada banyak fungsi dan operator lain yang dapat digunakan untuk membandingkan nilai skalar, tetapi mengetahui perbedaan antara kedua bentuk ini merupakan langkah pertama yang penting.

Brent Bradburn
sumber
Java memiliki masalah yang sama, tetapi karena alasan yang berbeda (dan dengan implikasi yang berbeda).
Brent Bradburn
1

Dan jika Anda ingin mengekstraksi perbedaan antara kedua string, Anda dapat menggunakan String :: Diff .

Helen Craigman
sumber
Jika Anda akan menautkan ke dokumentasi Perl, biasanya disarankan untuk menggunakan Permalinks yang akan selalu tertaut ke versi terbaru dari modul. 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