Подстановка строки в perl заменяет строку на целочисленное значение - PullRequest
0 голосов
/ 24 апреля 2019

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

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

#! /usr/intel/bin/perl

my $line = "foo/\\bar car"; 
print "$line\n";
#$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 "$line\n"; 

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

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

Ответы [ 2 ]

3 голосов
/ 24 апреля 2019

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

$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.
0 голосов
/ 29 апреля 2019

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

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

$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-битной системе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...