Як я порівнюю два рядки в Perl?
Я вивчаю Perl, у мене на це основне запитання було розглянуто його тут, на StackOverflow, і я не знайшов хорошої відповіді, тому я подумав, що запитаю.
Як я порівнюю два рядки в Perl?
Я вивчаю Perl, у мене на це основне запитання було розглянуто його тут, на StackOverflow, і я не знайшов хорошої відповіді, тому я подумав, що запитаю.
Відповіді:
Див. 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 :: Локальні модулі пропонують набагато більш потужні рішення проблем зіставлення.
index
щоб перевірити, чи є рядок підрядком іншої.
!=
і ne
не однакові, тому що !=
і ne
визначаються як різні. Як важко це ?! Будучи оператором чисельного порівняння, !=
перетворює обидва його операнди в числа perl -E 'say "equal" if not "a" != "b"'
.
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. Ви дійсно повинні використовувати лише повернені значення для булевих чи числових операцій, і в цьому випадку різниця насправді не має значення.)
eq
, gt
, і lt
т.д., не правильно ... Вони повертаються істинним або хибним. cmp
Повертає лише певні числові значення.
leg
замість cmp
них для загальних порівнянь.
На додаток до вичерпного переліку операторів порівняння рядків 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
.
print "Matched!\n" if ($str1 eq $str2)
Perl має окремі оператори порівняння рядків та числових операторів порівняння, щоб допомогти з друкуванням мови. Ви повинні прочитати перлоп для всіх різних операторів.
Очевидним підтекстом цього питання є:
чому ви не можете просто
==
перевірити, чи дві струни однакові?
У 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
Коротко:
==
або !=
, щоб порівняти два операнди як числаeq
або ne
, щоб порівняти два операнди як текстІснує багато інших функцій та операторів, які можна використовувати для порівняння скалярних значень, але знання відмінності між цими двома формами є важливим першим кроком.
І якщо ви хочете витягнути відмінності між двома рядками, ви можете використовувати String :: Diff .