Как сравнить две строки в Perl?
Как сравнить две строки в Perl?
Я изучаю Perl, у меня был этот основной вопрос, посмотрев его здесь на StackOverflow и не нашел хорошего ответа, поэтому я подумал, что спрошу.
Ответы
Ответ 1
См. perldoc perlop. Используйте lt
, gt
, eq
, ne
и cmp
для соответствия строк:
Двоичный eq
возвращает true, если левый аргумент в строчном порядке равен правильному аргументу.
Двоичный ne
возвращает значение true, если левый аргумент не соответствует правильному аргументу.
Двоичный cmp
возвращает -1, 0 или 1 в зависимости от того, является ли левый аргумент строковым меньше, равным или большим, чем правый аргумент.
Двоичный ~~
выполняет smartmatch между его аргументами....
lt
, le
, ge
, gt
и cmp
используют порядок сортировки (сортировки), заданный текущей локалью, если действующий язык использования (но не use locale ':not_characters'
) действует. См. perllocale. Не смешивайте их с Unicode, только с устаревшими двоичными кодировками. Стандартные Unicode::Collate и Unicode::Collate::Locale модули предлагают много более мощные решения проблем сортировки.
Ответ 2
-
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. Фактически вы должны использовать только возвращаемые значения для логических или числовых операций, и в этом случае разница не имеет значения.)
Ответ 3
В дополнение к всеобъемлющему списку операторов сравнения строк Sinan Ünür Perl 5.10 добавляет оператор интеллектуального соответствия.
Оператор smart match сравнивает два элемента в зависимости от их типа. См. Диаграмму ниже для поведения 5.10 (я считаю, что это поведение немного меняется в 5.10.1):
Поведение умного соответствия зависит от того, что это за аргументы. Он всегда коммутативен, т.е. $a ~~ $b
ведет себя так же, как $b ~~ $a
. Поведение определяется следующей таблицей: первая строка, которая применяется в любом порядке, определяет поведение совпадения.
$a $b Type of Match Implied Matching Code
====== ===== ===================== =============
(overloading trumps everything)
Code[+] Code[+] referential equality $a == $b
Any Code[+] scalar sub truth $b−>($a)
Hash Hash hash keys identical [sort keys %$a]~~[sort keys %$b]
Hash Array hash slice existence grep {exists $a−>{$_}} @$b
Hash Regex hash key grep grep /$b/, keys %$a
Hash Any hash entry existence exists $a−>{$b}
Array Array arrays are identical[*]
Array Regex array grep grep /$b/, @$a
Array Num array contains number grep $_ == $b, @$a
Array Any array contains string grep $_ eq $b, @$a
Any undef undefined !defined $a
Any Regex pattern match $a =~ /$b/
Code() Code() results are equal $a−>() eq $b−>()
Any Code() simple closure truth $b−>() # ignoring $a
Num numish[!] numeric equality $a == $b
Any Str string equality $a eq $b
Any Num numeric equality $a == $b
Any Any string equality $a eq $b
+ − this must be a code reference whose prototype (if present) is not ""
(subs with a "" prototype are dealt with by the 'Code()' entry lower down)
* − that is, each element matches the element of same index in the other
array. If a circular reference is found, we fall back to referential
equality.
! − either a real number, or a string that looks like a number
Разумеется, "код соответствия" не представляет собой настоящий код соответствия: он просто объясняет предполагаемое значение. В отличие от grep, оператор smart match будет замыкаться каждый раз, когда это возможно.
Пользовательское сопоставление через перегрузку
Вы можете изменить способ сопоставления объекта путем перегрузки оператора ~~
. Это превосходит обычную интеллектуальную семантику соответствия. См. overload
.
Ответ 4
print "Matched!\n" if ($str1 eq $str2)
У Perl есть отдельные операторы сравнения строк и числовые сравнения, которые помогут вам свободно печатать на этом языке. Вы должны прочитать perlop для всех разных операторов.
Ответ 5
Очевидный подтекст этого вопроса:
почему вы не можете просто использовать ==
для проверки того, являются ли две строки одинаковыми?
Perl не имеет разных типов данных для текста и чисел. Они оба представлены типом "scalar" . Иными словами, строки - это числа если вы используете их как таковые.
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
, чтобы сравнить два операнда в виде текста
Существует множество других функций и операторов, которые могут использоваться для сравнения скалярных значений, но знание различия между этими двумя формами является важным первым шагом.
Ответ 6
И если вы хотите извлечь различия между двумя строками, вы можете использовать String:: Diff.