用sed替换两个模式之间的多个惰性字符串

时间:2015-12-16 12:10:19

标签: regex bash shell sed

示例:

This (word1) is a test (word2) file.

我想要的是什么:

This is a test file.

问题是括号出现不止一次,所以如果我使用:

sed 's/<.*>//g'

我得到This file,这是错误的。

如果我想在两个相同的模式之间替换字符串怎么样?

像:

WORD1 %WORD2% WORD3 => WORD1 WORD3

1 个答案:

答案 0 :(得分:4)

你所需要的只是一个否定的角色等级[^<>]*,它会匹配除<>之外的任何角色:

sed 's/<[^<>]*>//g'

或者,如果您使用圆括号,则可以使用[^()]*(请注意,在BRE语法中,匹配文字()转义\不是必需的) :

sed 's/([^()]*)//g'

请参阅IDEONE demo

对于更新,您可以使用WORD1删除从WORD3.*的所有内容,但只有在WORD1和{只有WORD3时才能删除 {1}} demo):

echo "WORD1 %WORD2% WORD3" | sed 's/WORD1.*WORD3/WORD1 WORD3/g'

使用时,无法使用lookarounds(此处为lookahead),也不能使用延迟量词将匹配限制为最左侧WORD3次出现。如果你确定中间没有%符号,你仍然可以使用否定的字符类方法(demo):

echo "WORD1 %WORD2% WORD3" | sed 's/%[^%]*%//g'

通用解决方案是通过以下几个步骤完成的:

  • 未使用的字符<UC>)替换起始分隔符和结尾分隔符(我使用的是俄语字母,但它应该是一些控制字符)
  • 使用否定字符类<UC1>[^<UC1><UC2>]*<UC2>替换必要的替换字符串
  • 恢复初始分隔符。

这是example

#!/bin/bash
echo "WORD1 %WORD2% WORD3 some text WORD1 %WORD2% WORD3" | 
  sed 's/WORD1/й/g' |
  sed 's/WORD3/ч/g' |
  sed 's/й[^йч]*ч/й ч/g' |
  sed 's/й/WORD1/g' |
  sed 's/ч/WORD3/g' 
 // => WORD1 WORD3 some text WORD1 WORD3

我正在硬编码空间,但可以在必要时进行调整。