Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 为什么在这个正则表达式替换中引号的转义丢失了?_Regex_Bash_Perl - Fatal编程技术网

Regex 为什么在这个正则表达式替换中引号的转义丢失了?

Regex 为什么在这个正则表达式替换中引号的转义丢失了?,regex,bash,perl,Regex,Bash,Perl,为什么在这种情况下双引号的转义会丢失 $ cat foo.txt This is a \"very good\" text worth AMOUNT dollars $ cat full_story.txt This is about money: STORY 使用以下各项对其进行测试: VAR=$(cat foo.txt)

为什么在这种情况下双引号的转义会丢失

$ cat foo.txt   
This is a \"very good\" text worth AMOUNT dollars    
$ cat full_story.txt   
This is about money:  
STORY  
使用以下各项对其进行测试:

VAR=$(cat foo.txt)                                                                                         
TOTAL=$(cat full_story.txt)  
echo "$TOTAL" | perl -pe "s/STORY/$VAR/g"  
结果:

This is about money:  
This is a "very good" text worth AMOUNT dollars  
双引号的逃逸迷失了方向。我期待着:

This is about money:  
This is a \"very good\" text worth AMOUNT dollars  

我怎样才能保存这些逃犯

问题在于
perl
解析显式替换字符串中的反斜杠转义(不是
perl
变量),因此
\“
被解析为
。例如:

$ echo "A STORY" | perl -pe 's/STORY/\"Hello\"/'
A "Hello"
(请注意,Bash变量
$VAR
不会变成
perl
变量
$VAR
,而是一个常量字符串。)因此,您需要在常量字符串中像这样转义反斜杠:

$ echo "A STORY" | perl -pe 's/STORY/\\"Hello\\"/' 
A \"Hello\"
您可以通过使用切换到
perl
将Bash变量
$VAR
转换为
perl
变量
$VAR
来解决此问题,如下所示:

echo "$TOTAL" | perl -spe 's/STORY/$VAR/g' -- -VAR="$VAR"
输出

This is about money:  
This is a \"very good\" text worth AMOUNT dollars
说明:

  • -s
    perl
    命令行上为用户定义的开关启用开关解析。在那里找到的任何开关都将从
    @ARGV
    中删除,并在Perl程序中设置相应的变量
您的代码存在错误。具体来说,您试图从shell生成Perl代码,但失败了

您正在将以下内容传递给Perl:

s/STORY/This is a \"very good\" text worth AMOUNT dollars/g
您应该通过以下考试:

s/STORY/This is a \\"very good\\" text worth AMOUNT dollars/g
perl -pe's/STORY/'"$( printf %s "$VAR" | sed 's/\W/\\&/g' )"'/'

要正确生成Perl代码,您需要以下内容:

s/STORY/This is a \\"very good\\" text worth AMOUNT dollars/g
perl -pe's/STORY/'"$( printf %s "$VAR" | sed 's/\W/\\&/g' )"'/'
这会将以下内容传递给Perl(这也很好):


不过,首先避免生成Perl代码要简单得多。有三种主要方法可以在不使用STDIN或外部存储的情况下将信息传递给Perl

  • 论据

    perl -pe'BEGIN { $VAR = shift(@ARGV) } s/STORY/$VAR/g' -- "$VAR"
    
  • 命令行选项

    在一个完整的程序中,您可以使用,但在这里会做得很好

    perl -spe's/STORY/$VAR/g' -- -VAR="$VAR"
    
  • 环境变量

    VAR="$VAR" perl -pe's/STORY/$ENV{VAR}/g'
    

为什么要投否决票?这篇文章有什么问题?把你的反斜杠加倍,或者引用
foo.txt
中的文本,比如
“这是…”
@keithpjolley:1)引用
这是…
仍然会删除转义。这也不是我想要的,因为我不知道那句话引用了什么2)做双转义可以解决这个问题,但我宁愿不做,因为副本有转义already@keithpjolley:+1尽管如此,双转义仍然有效。我想理解为什么这种方法不起作用,这只是用光了我头脑中最后一点perl知识:
echo“$TOTAL”| perl-pe'$v=q{'$VAR'};s/STORY/$v/g'
。我相信有不同的方法可以做到这一点。另一种解决方法是说:
echo“$TOTAL”| perl-pe“s'STORY'$VAR'g”
,因此
替换的内容可以被逐字解析。@tshiono谢谢,观察得很好。我已将你的建议编辑成我的答案。@HåkonHægland:非常有用!在
--VAR=“$VAR”
中,为什么需要
VAR
前面的破折号?也就是说,为什么它不是
--VAR=“$VAR”
?我无法从你粘贴的文档中理解它应该是这样的是的,我也认为文档在thant点不是很清楚。有关更多信息,请参见答案。因此,我认为需要用破折号将
-VAR
和其他用户开关与普通的
perl
选项分开。我对它进行了一点测试,您甚至可以通过添加另一个
--
的实例来混合普通参数(
@ARGV
),如下所示:
perl-sE'say':ARGV=“,join”|“,@ARGV;说“VAR=$VAR”--VAR=ss--1 2 3
@ikegami抓得好!因此,第一种使用
-s
的方法比第二种不使用
-s
的方法更正确?太棒了!一个问题:基本上,如果我在文本中有“非常好”
,所有这些都是不必要的?所以你建议放一段Perl代码——甚至不是一个完整的标记在您的数据文件中。这是自找麻烦,这是个可怕的主意。我已经说过以下几次了,但它似乎没有被理解:不要试图从shell生成Perl代码!等待你的意思是“非常好”是perl代码吗?啊,我现在明白了。我不明白这取决于
VAR1
是一个正则表达式模式,还是一个字面上匹配的文本字符串。很可能是后者,所以您刚刚引入了一个新的代码注入。您需要将文本转换为正则表达式:
perl-pe的/\Q$ENV{VAR1}/$ENV{VAR2}/g'
通过切换到双引号,您使
$
成为shell的特殊部分。