Замена строки в perl изменяет строку на целое значение

#perl

#perl

Вопрос:

Я пытаюсь удалить некоторые символы, соответствующие регулярному выражению в perl, и когда я это делаю, оно возвращает целочисленное значение.

Я попытался заменить несколько пробелов в строке пустой строкой или в основном удалить пробел.

 #! /usr/intel/bin/perl

my $line = "foo/\bar car"; 
print "$linen";
#$line = ~s/(\|(s) ) //; <--Ultimately need this, where backslash and space needs to be deleted. Tried this, returns integer value
$line = ~s/s //; <-- tried this, returns integer value
print "$linen"; 
  

Ожидаемые результаты:
Первая печать: foo/bar car
Вторая печать: foo/barcar

Фактический результат:
Первая печать: foo/\bar car
Вторая печать: 18913234908

Комментарии:

1. Есть разница между =~ и = ~

2. Вы должны use warnings; .

Ответ №1:

Правильное решение

 $line =~ s/[s\] //g;
  

Примечание:

  • g установите флажок для замены всех вхождений
  • нет пробела между = и ~

=~ является единственным оператором, привязывающим оператор подстановки s к целевой переменной $line .

Вставка пробела (как в вашем коде) означает s привязку к цели по умолчанию, $_ потому что нет явной цели, а затем возвращаемое значение (которое представляет собой количество сделанных замен) имеет все свои биты, инвертированные (унарный ~ является побитовым дополнением) и присваивается $line .

Другими словами,

 $line = ~ s/...//
  

разбирается как

 $line = ~(s/...//)
  

что эквивалентно

 $line = ~($_ =~ s/...//)
  

Если бы вы включили use warnings , вы бы получили следующее сообщение:

 Use of uninitialized value $_ in substitution (s///) at prog.pl line 6.
  

Ответ №2:

Вы уже приняли ответ, но я подумал, что было бы полезно предоставить вам еще несколько деталей.

Как вы теперь знаете,

 $line = ~s/s //;
  

полностью отличается от:

 $line =~ s/s //;
  

Вы хотели второе, но ввели первое. Итак, что вы получили в итоге?

~ является «побитовым оператором отрицания». То есть он преобразует свой аргумент в двоичное число, а затем переворачивает это число — все нули становятся единицами, а все единицы становятся нулями.

Итак, вы просите побитовое отрицание s/s // . Что означает, что побитовое отрицание работает со значением, возвращаемым s/s // . А значение, возвращаемое подстановкой, — это количество сделанных замен.

Теперь мы можем проработать все детали.

  • s/s // выполняет вашу подстановку и возвращает количество сделанных замен (целое число).
  • ~s/s // возвращает побитовое отрицание целого числа, возвращаемого подстановкой (которое также является целым числом).
  • $line = ~s/s // берет это второе целое число и присваивает его переменной $line .

Вероятно, первый шаг возвращает 1 (вы не используете /g на своем s/.../.../ , поэтому будет произведена только одна замена). Достаточно легко получить побитовое отрицание 1.

 $ perl -E'say ~1'
18446744073709551614
  

Так что это вполне может быть целым числом, которое вы видите (хотя в 32-разрядной системе оно может отличаться).