Как сравнить две строки в 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):

perldoc perlsyn "Умное соответствие в деталях" :

Поведение умного соответствия зависит от того, что это за аргументы. Он всегда коммутативен, т.е. $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.