#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-разрядной системе оно может отличаться).