当我使用这个表达时:
echo '...${var}#other.([]);,=${var}#other${var}...' | perl -pe 's/\Q.([]);,=${var}\E/.([]);,=ok/'
正如预期的那样,变量${var}
被扩展为“”(空值)并得到输出:
...${var}#other.([]);,=ok${var}#other${var}...
但我想要:
...${var}#other.([]);,=ok#other${var}...
所以我考虑逃避变量:
echo '...${var}#other.([]);,=${var}#other${var}...' | perl -pe 's/\Q.([]);,=\${var}\E/.([]);,=ok/'
由于某些我不知道的原因,提供的字符串与输入的字符串的一部分不匹配,因此不会被替换:
...${var}#other.([]);,=${var}#other${var}...
双反斜杠\\$
和三\\\$
反斜杠也不匹配。
我哪里做错了?
答案1
查看\Q
文档man perlop
:
For the pattern of regex operators ("qr//", "m//" and "s///"), the quoting from "\Q" is
applied after interpolation is processed, but before escapes are processed. This allows
the pattern to match literally (except for "$" and "@"). For example, the following
matches:
'\s\t' =~ /\Q\s\t/
Because "$" or "@" trigger interpolation, you'll need to use something like
"/\Quser\E\@\Qhost/" to match them literally.
并且,检查文档quotemeta
(用于\Q ... \E
内部实现)man perlfunc
:
Beware that if you put literal backslashes (those not inside interpolated variables)
between "\Q" and "\E", double-quotish backslash interpolation may lead to confusing
results. If you need to use literal backslashes within "\Q...\E", consult "Gory
details of parsing quoted constructs" in perlop.
Because the result of "\Q STRING \E" has all metacharacters quoted, there is no way to
insert a literal "$" or "@" inside a "\Q\E" pair. If protected by "\", "$" will be
quoted to become "\\\$"; if not, it is interpreted as the start of an interpolated
scalar.
因此$
不能将其保留在里面\Q ... \E
。您必须执行以下操作:
% echo '...${var}#other.([]);,=${var}#other${var}...' | perl -pe 's/\Q.([]);,=\E\$\Q{var}\E/.([]);,=ok/'
...${var}#other.([]);,=ok#other${var}...