如何在应用于字符串的替换函数中使用 RegEx 来匹配子字符串的所有实例,第一个实例除外?
例如,如果我要替换除第一个以外的所有 'a' 并且我的字符串是:
a b a c b a a b
我想得到:
a b c b b
我的实际用例是我正在使用 Ant 构建一个项目,它将一堆 .js 文件连接成一个。每个 javascript 文件都以:“use strict”开头。我只想要这个声明一次,因此我希望删除这个子字符串的所有实例,除了开头的那个。
如何在应用于字符串的替换函数中使用 RegEx 来匹配子字符串的所有实例,第一个实例除外?
例如,如果我要替换除第一个以外的所有 'a' 并且我的字符串是:
a b a c b a a b
我想得到:
a b c b b
我的实际用例是我正在使用 Ant 构建一个项目,它将一堆 .js 文件连接成一个。每个 javascript 文件都以:“use strict”开头。我只想要这个声明一次,因此我希望删除这个子字符串的所有实例,除了开头的那个。
这是一个通用的正则表达式:
echo "a b a c b a a b" | perl -pWe 's/(?<=(a))(.*?)\1/$2/g'
它使用lookbehind来检查匹配的模式是否在字符串的第一个。(基本上,我的想法是s/(?<=(a).*?)\1//g
,但可变长度的后视似乎并没有被广泛实施)。有一个缺点 - 它会产生类似的输出
a b c b b
为了使其整洁,您可以使用
echo "a b a c b a a b" | perl -pWe 's/(?<=(a\s))(.*?)\1/$2/g'
但它不会删除a
输入中的最后一个,比如a b a c b a a
只需删除所有出现的"use strict";
,然后在开始时再次添加一个。
编辑:示例:
sed '/"use strict";/d' < infile > outfile
变成
(echo '"use strict"'; sed '/"use strict";/d') < infile > outfile
perl -nie 'print unless /"use strict";/;' file
变成
perl -nie 'BEGIN { print qq["use strict";\n]; } print unless /"use strict";/;' file
要解决您的示例,您可以使用否定的前瞻断言:
echo "a b a c b a a b" | perl -pe 's/(?!^)a //g'
结果:
a b c b b
要解决您的项目问题(假设use strict
在您的连接文件的每一行上没有多次出现),您可以使用GNU sed
删除除第一个之外的所有出现:
sed '0,/$/!s/use strict//g' file.txt