Sed 正则表达式和子字符串否定 [英] Sed regex and substring negation
问题描述
查找与特定模式不匹配的子字符串(前后为特定字符串的字符串)的正确语法是什么?
What is the correct syntax for finding a substring (a string which is preceded and followed by specific strings) which does not match a specific pattern?
例如,我想取以BEGIN_
开始、以_END
结束和结束的所有子字符串中间的子串不等于FOO
;并将整个子字符串替换为(inner substring)"格式.以下将匹配:
For example, I want to take all substrings which start with BEGIN_
, end with _END
and the substring in between is not equal to FOO
; and replace the whole substring with the format "(inner substring)". The following would match:
BEGIN_bar_END
->(bar)
BEGIN_buz_END
->(buz)
BEGIN_ihfd8f398IHFf9f39_END
->(ihfd8f398IHFf9f39)
BEGIN_bar_END
->(bar)
BEGIN_buz_END
->(buz)
BEGIN_ihfd8f398IHFf9f39_END
->(ihfd8f398IHFf9f39)
但是 BEGIN_FOO_END
不匹配.
我尝试了以下内容,但似乎找不到正确的语法:
I have played around with the following, but cannot seem to find the correct syntax:
sed -e 's/BEGIN_(^FOO)_END/($1)/g'
sed -e 's/BEGIN_([^FOO])_END/($1)/g'
sed -e 's/BEGIN_(?!FOO)_END/($1)/g'
sed -e 's/BEGIN_(!FOO)_END/($1)/g'
sed -e 's/BEGIN_(FOO)!_END/($1)/g'
sed -e 's/BEGIN_!(FOO)_END/($1)/g'
推荐答案
sed
中没有通用的否定运算符,IIRC 因为将带有否定的正则表达式编译为 DFA 需要指数级的时间.你可以解决这个问题
There is no general negation operator in sed
, IIRC because compilation of regexes with negation to DFAs takes exponential time. You can work around this with
'/BEGIN_FOO_END/b; s/BEGIN_\(.*\)_END/(\1)/g'
其中 /BEGIN_FOO_END/b
表示:如果我们找到 BEGIN_FOO_END
,则 branch(跳转)到 sed 的末尾
脚本.
where /BEGIN_FOO_END/b
means: if we find BEGIN_FOO_END
, then branch (jump) to the end of the sed
script.
这篇关于Sed 正则表达式和子字符串否定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!