[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 使用sed用正则替换文本时,什么情况下竖线【|】前要加^

本帖最后由 kidzgy 于 2023-8-8 01:57 编辑

【extensions.json】内容
  1. "rootURI":"jar:file:///D:/Firefox115/Profiles/extensions/uBlock0@raymondhill.net.xpi!/","location":"app-profile"
  2. "path":"D:\\Firefox115\\Profiles\\extensions\\s3google@translator.xpi","skinnable":false,
复制代码
【sed.bat】内容
  1. @ECHO OFF&(PUSHD "%~DP0")
  2. set "firefox=%~dp0"
  3. sed.exe -i -r "s#(jar:file:\/\/\/)[^^,]+(profiles\/extensions|browser\/features)\/#\1%firefox:\=/%\2#gi" "extensions.json"
  4. sed.exe -i -r "s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi" "extensions.json"
  5. exit
复制代码



有个问题不明白,sed第一个替换语句,竖线【|】前是不用加【^】的,加了反而没有效果,第二个语句却是要加【^】,删除了反而没有效果。这两者为什么一个要加,一个不用加,百思不得其解。

【^】是bat的转义吧,竖线【|】是bat的管道符
第一个正好2对英文双引号,被当成2个字符串,因此不需要对【|】用【^】进行转义
第二个中的
"s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"
应该是被bat当成了
s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\\2#gi
如果不用【^】对【|】进行转义的话,【|】会被bat当成管道符

可以试试直接echo一下看看,对比一下第二个带【^】和不带【^】的输出
echo "s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"
echo "s#(\"path\":\")[^^,]+(profiles\\\\extensions|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"

大概是这样子吧

TOP

【^】是bat的转义吧,竖线【|】是bat的管道符
第一个正好2对英文双引号,被当成2个字符串,因此不需要对【 ...
Five66 发表于 2023-8-8 13:11



    原来如此,谢谢答疑解惑。

我发现,在【|】之前,双引号个数不能是偶数个,这里的数量包括【s#】前的双引号,如果是偶数个,【|】之前就要加上【^】。

TOP

回复 3# kidzgy


    呃,可是1楼的bat里的sed 不都是奇数个么?

TOP

本帖最后由 kidzgy 于 2023-8-8 16:08 编辑

回复 4# Five66

第一个sed是奇数,第二个sed是偶数。
    所以在|前有奇数个双引号时,|前不需要加^。

TOP

因为在没有开延迟变量扩展时,预处理不会处理双引号内的特殊符号。

TOP

回复 2# Five66


    问题一: 两段是不是:"s#(jar:file:\/\/\/)[^^,]+(profiles\/extensions|browser\/features)\/#\1%firefox:\=/%\2#gi" "extensions.json" 这两段?

    问题二:第二个中的
               "s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"
               应该是被bat当成了
               s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\\2#gi
         是解释器去掉引号了吗?为什么一对比,好像不光这样,第二句比第一句还少了个%,以及如果是这种说法,猜想,或者机制的话,那"s#(jar:file:\/\/\/)[^^,]+(profiles\/extensions|browser\/features)\/#\1%firefox:\=/%\2#gi" "extensions.json" 不也会被去掉双引号,而|符被当成管道符吗?

TOP

回复 7# GNGW


    那是参数 , 会按一定规则去掉引号 (保留引号内的内容), 然后传递到命令中

TOP

回复 7# GNGW


    可以这样理解:
一般来说,双引号一般会成对出现,被 "双引号对" 包裹的字符串,其中的特殊字符并不需要转义。
因为成对出现的双引号,本身就具有转义特殊字符的作用。比如 echo "a|b" 中的特殊字符不需要转义。
但暴露在 "双引号对" 之外的字符串,其中的特殊字符需要转义。

"s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"

红色、蓝色分别是两组被双引号包裹的字符串,剩余的字符串都暴露在 "双引号对" 的外面,暴露在外边的特殊字符^和|都要转义。

TOP

顺便说下,顶楼脚本不知楼主从哪抄的,单从 sed 语法上讲,很多转义是多余的。
  1. sed -i -r "s#(jar:file:///)[^,]+(profiles/extensions|browser/features)/#\1%firefox:\=/%\2#gi" a.txt
复制代码
  1. sed -i -r "s#(\x22path\x22:\x22)[^,]+(profiles\\\\extensions|browser\\\\features)#\1%firefox:\=\\\\%\2#gi" a.txt
复制代码

TOP

回复  GNGW


    可以这样理解:
一般来说,双引号一般会成对出现,被 "双引号对" 包裹的字符串,其中 ...
WHY 发表于 2024-3-20 22:23



    那这样说的话,最后一个双引号和谁配对?没有配对也没有转义,解释器不会报语法错误?

TOP

回复 8# Five66


    "s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\%\2#gi"
               应该是被bat当成了
               s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\\2#gi

我是说在您的回复中同样的位置,第一行和第二行对比是不是少了个%这是您没打字没打上,还是说蓄意为之。如果是的话,这又是什么语法,为什么解释器要去掉%?还有根据您上一次的回答这个答案中,如果规则中去掉最外围的双引号后,在
s#(\"path\":\")[^^,]+(profiles\\\\extensions^|browser\\\\features)#\1%firefox:\=\\\\\2#gi 还是有一个双引号没被配对。

TOP

回复 12# GNGW


    啊 , 确实是少了%
至于还是有一个双引号没被配对 , 那是因为跟参数解析规则并在了一起 , 参数解析规则中的\"其实就表示"(即转义")
分开来的话就像9楼说的那样 , cmd会先将命令和参数部分分解出来 , 然后再将参数部分按一定规则进行解析 传进命令里
参数解析规则参考
http://www.bathome.net/thread-3451-1-20.html

TOP

回复 13# Five66


    所以根据这个结论,为什么要有两个转义字符?它们的作用范围或者说使用场景是不是不同?如何分别和搭配使用?
吹毛求疵的人,找问题的人,好奇心强的人,动手能力强的人,虚心的人,以及一个简单的研究技术的人。

TOP

回复  Five66

第一个sed是奇数,第二个sed是偶数。
    所以在|前有奇数个双引号时,|前不需要加^。
kidzgy 发表于 2023-8-8 16:07



    这个原因是因为预处理机制,在没有开延迟变量扩展的时候,在双引号的时候视为转义,(希望不要误解到你,这是我了解到的,不保证一定准确性,但肯定是双符号是转义),比如%%可以视为转义,\\,^^,“”,还有很多,http://www.bathome.net/redirect. ... 8649&pid=279265 我把帖子贴在这里,注意,帖子里的有些内容机制我也没有搞懂,所以分析之后可以跟帖纠正,或者补充,
吹毛求疵的人,找问题的人,好奇心强的人,动手能力强的人,虚心的人,以及一个简单的研究技术的人。

TOP

返回列表