Як я порівнюю два рядки в Perl?


178

Як я порівнюю два рядки в Perl?

Я вивчаю Perl, у мене на це основне запитання було розглянуто його тут, на StackOverflow, і я не знайшов хорошої відповіді, тому я подумав, що запитаю.


3
Спершу слід ознайомитися з чудовою документацією, яка постачається разом з Perl.
Sinan Ünür

5
Можливо, ви захочете переглянути книгу, наприклад, Learning Perl (яку я є співавтором). На це питання не було гарних відповідей, тому що це дуже просто. Підручник допоможе вам швидко підібрати основи.
Брайан d foy

Відповіді:


184

Див. Perldoc perlop . Використовуйте lt, gt, eq, ne, і cmpу відповідних випадках для порівняння рядків:

Двійковий eqповертає істину, якщо лівий аргумент є строко рівним правим аргументом.

Двійкові ne повертає істину, якщо лівий аргумент по рядку не дорівнює правильному аргументу.

Двійковий cmpповертає -1, 0 або 1 залежно від того, чи лівий аргумент є строковим меншим, рівним або більшим за правий аргумент.

Binary ~~робить smartmatch між своїми аргументами. ...

lt, le, ge, gtІ cmpвикористовувати параметри сортування (сортування) порядок , зазначений в поточній локалі , якщо в спадок використання локалі (але не use locale ':not_characters') діє. Дивіться perllocale . Не змішуйте їх з Unicode, лише зі застарілими двійковими кодуваннями. Стандартні Unicode :: Collate і Unicode :: Collate :: Локальні модулі пропонують набагато більш потужні рішення проблем зіставлення.


9
Ще один, не для не рівних.
PJT

4
Ви можете згадати, що $ str1 = ~ "$ str2" (not / $ str2 /) перевірить, чи $ str2 є підрядком $ str1.
Даніель Ч. Собрал

@Daniel використовує, indexщоб перевірити, чи є рядок підрядком іншої.
Sinan Ünür

3
@Daniel: немає великої практичної різниці між = ~ "$ str2" і = ~ / $ str2 / (або просто = ~ $ str2 з цього приводу); index - це правильний інструмент, але якщо вам потрібно чомусь використовувати регулярний вираз, зробіть = ~ / \ Q $ str2 \ E /.
ysth

1
@IliaRostovtsev !=і neне однакові, тому що !=і neвизначаються як різні. Як важко це ?! Будучи оператором чисельного порівняння, !=перетворює обидва його операнди в числа perl -E 'say "equal" if not "a" != "b"'.
Sinan Ünür

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 за винятком того, що повертаються значення для eq, gt, і ltт.д., не правильно ... Вони повертаються істинним або хибним. cmpПовертає лише певні числові значення.
Sinan Ünür

Perl 6 використовує ті самі оператори, за винятком тих, що використовуються legзамість cmpних для загальних порівнянь.
Бред Гілберт

17

На додаток до вичерпного переліку операторів порівняння рядків Sinan Ünür Perl 5.10 додає оператора розумних відповідностей.

Оператор розумної відповідності порівнює два елементи залежно від їх типу. Дивіться діаграму нижче щодо поведінки 5.10 (я вважаю, що ця поведінка незначно змінюється в 5.10.1):

perldoc perlsyn"Розумне узгодження в деталях" :

Поведінка розумного матчу залежить від того, до якого типу речі належать його аргументи. Він завжди комутативний, тобто $a ~~ $bповодиться так само, як $b ~~ $a. Поведінка визначається наступною таблицею: перший рядок, який застосовується в будь-якому порядку, визначає поведінку відповідності.

  $ a $ b Тип відповідного коду відповідного коду
  ====== =========================================
  (перевантажує козирі все)

  Код [+] Код [+] референсна рівність $ a == $ b   
  Будь-який код [+] скалярна істина $ b -> ($ a)   

  Hash Hash-хеш-ключі ідентичні [клавіші сортування% $ a] ~~ [сортування ключів% $ b]
  Хеш-масив існування хеш-фрагмента grep {існує $ a -> {$ _}} @ $ b
  Hash Regex хеш-ключ grep grep / $ b /, ключі% $ a
  Hash Будь-яке існування хеш-запису існує $ a -> {$ b}

  Масиви масивів масивів ідентичні [*]
  Масив Regex масив grep grep / $ b /, @ $ a
  Масив Num масив містить число grep $ _ == $ b, @ $ a 
  Масив Будь-який масив містить рядковий греп $ _ eq $ b, @ $ a 

  Будь-який undef undefined! Визначений $ a
  Будь-який зразок Regex відповідає $ a = ~ / $ b / 
  Результати Code () Code () рівні $ a -> () eq $ b -> ()
  Будь-який код () проста істина закриття $ b -> () # ігнорування $ a
  Num numish [!] Числова рівність $ a == $ b   
  Будь-яка рівність Str струна $ a eq $ b   
  Будь-яка числова рівність $ a == $ b   

  Будь-яка будь-яка рівність рядків $ a eq $ b   

+ - це повинна бути посилання на код, прототип якого (якщо він присутній) не ""
(підпрограми з прототипом "" обробляються записом "Code ()" внизу) 
* - тобто кожен елемент відповідає елементу того ж індексу в іншому
масив. Якщо буде знайдено кругле посилання, ми повернемося до референтного
рівність.   
! - або реальне число, або рядок, схожий на число

Звичайно, "відповідний код" не представляє реального відповідного коду: він просто є для пояснення наміченого значення. На відміну від grep, оператор розумних матчів замикатиметься, коли тільки може.

Спеціальне узгодження за допомогою перевантаження Ви можете змінити спосіб узгодження об'єкта, перевантажуючи ~~оператора. Це козиряє звичайну семантику розумних матчів. Див overload.


Це не мало змінюється: змінюється докорінно. Розумне узгодження будь-чого не простого серйозно порушено.
Brian d foy

1
Посилання, мабуть, має змінитися, оскільки документи змінилися в середній час. 5.14.2 поточно
Бред Гілберт

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

Perl має окремі оператори порівняння рядків та числових операторів порівняння, щоб допомогти з друкуванням мови. Ви повинні прочитати перлоп для всіх різних операторів.


8

Очевидним підтекстом цього питання є:

чому ви не можете просто ==перевірити, чи дві струни однакові?

У 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 немає типу даних виключно для текстових рядків
  • використовувати ==або !=, щоб порівняти два операнди як числа
  • використовувати eqабо ne, щоб порівняти два операнди як текст

Існує багато інших функцій та операторів, які можна використовувати для порівняння скалярних значень, але знання відмінності між цими двома формами є важливим першим кроком.


У Java є та сама проблема, але з іншої причини (і з різними наслідками).
Брент Бредберн

1

І якщо ви хочете витягнути відмінності між двома рядками, ви можете використовувати 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.