Ответ 1
Первый .*
соответствует символу a, затем он соответствует пустой строке после a. Может быть, вы хотите .+
?
Может ли кто-нибудь объяснить мне, почему вывод этого маленького perl script является "foofoo" (а не "foo" )?
#!/usr/bin/perl -w
my $var="a";
$var=~s/.*/foo/g;
print $var."\n";
Без опции g это работает, хотя я бы это сделал, но почему глобальный вариант сопоставляет шаблон дважды?
В bash вывод "foo" как ожидалось
echo "a"|sed -e "s/.*/foo/g"
Любое объяснение будет оценено.
Первый .*
соответствует символу a, затем он соответствует пустой строке после a. Может быть, вы хотите .+
?
Приятно, если вы попробуете
$var=~s/.*?/foo/g;
Вы получите
foofoofoo
Что? модификатор соответствует 1 или 0 раз. Если вы удалите g, вы получите
fooa
потому что он заменит только пустую строку, которую она найдет. Мне нравится perl.
Это потому, что вы используете .*
вместо .+
Модификатор * указывает механизму регулярного выражения совместить (и заменить в вашем примере) строку "a", затем строку нулевой длины (и заменить ее также).
Вы можете проверить это, используя это регулярное выражение в вашем примере кода:
$var=~s/(.*)/<$1>/g;
Затем вы увидите этот вывод:
"<a><>"
Если вы добавите re в свой код:
use re 'debug';
вы увидите, что регулярное выражение успешно совпадает дважды:
Compiling REx `.*'
size 3 Got 28 bytes for offset annotations.
first at 2
1: STAR(3)
2: REG_ANY(0)
3: END(0)
anchored(MBOL) implicit minlen 0
Offsets: [3]
2[1] 1[1] 3[0]
Matching REx ".*" against "a"
Setting an EVAL scope, savestack=5
0 <> <a> | 1: STAR
REG_ANY can match 1 times out of 2147483647...
Setting an EVAL scope, savestack=5
1 <a> <> | 3: END
Match successful!
Matching REx ".*" against ""
Setting an EVAL scope, savestack=7
1 <a> <> | 1: STAR
REG_ANY can match 0 times out of 2147483647...
Setting an EVAL scope, savestack=7
1 <a> <> | 3: END
Match successful!
Matching REx ".*" against ""
Setting an EVAL scope, savestack=7
1 <a> <> | 1: STAR
REG_ANY can match 0 times out of 2147483647...
Setting an EVAL scope, savestack=7
1 <a> <> | 3: END
Match possible, but length=0 is smaller than requested=1, failing!
failed...
Match failed
foofoo
Freeing REx: `".*"'