正则表达式否定:匹配特定字符串以外的模式

时间:2011-01-17 12:01:23

标签: regex sed regex-negation

我正在使用语音转文本应用程序,它将转录文件作为输出。转录的文本包含一些标签,如(s)(用于句子开头).. (/s)(用于句子结束) ).. (VOCAL_NOISE)(对于未识别的字词)..但文字中还包含不需要的标签,例如(VOCAL_N)(VOCAL_NOISED)(VOCAL_SOUND)(UNKNOWN) ..我正在使用SED来处理文本..但无​​法使用标记(s)来编写适当的正则表达式来替换除(/s)(VOCAL_NOISE)~NS之外的所有其他标记。如果有人可以帮助我,我将不胜感激。

示例文字:

(s) Hi Stacey , this is Stanley (/s) (s) I would (VOCAL_N) appreciate if you could call (UNKNOWN) and let him know I want an appointment (VOCAL_NOISE) with him (/s)

输出应为:

(s) Hi Stacey , this is Stanley (/s) (s) I would ~NS appreciate if you could call ~NS and let him know I want an appointment (VOCAL_NOISE) with him (/s)

5 个答案:

答案 0 :(得分:1)

这是一个肮脏的技巧,远非最佳,但它应该适合你:

sed ' 
    s|(\(/\?\)s)|[\1AAA]|g; 
    s|(VOCAL_NOISE)|[BBB]|g; 

    s/([^)]*)/~NS/g; 

    s|\[\(/\?\)AAA\]|(\1s)|g; 
    s|\[BBB\]|(VOCAL_NOISE)|g'

技巧是用输入文本中不存在的模式替换(s),(/ s)和(VOCAL_NOISE)(在这种情况下为[AAA],[/ AAA]和[BBB]);然后我们用~NS替换(。*)的每个实例;最后,我们将假图案恢复到原来的价值。

答案 1 :(得分:1)

这应该照顾它:

sed 's|([^)]*)|\n&\n|g;s@\n\((/\?s)\|(VOCAL_NOISE)\)\n@\1@g;s|\n\(([^)]*)\)\n|~NS|g' inputfile

说明:

  • s|([^)]*)|\n&\n|g - 将每个带括号的字符串放在两个换行符之间划分该行
  • s@\n\((/\?s)\|(VOCAL_NOISE)\)\n@\1@g - 删除“(s)”,“(/ s)”和“(VOCAL_NOISE)”(饲养员)周围的换行符
  • s|\n\(([^)]*)\)\n|~NS|g - 使用“~NS”替换括号内的换行符之间的任何其他内容

这是有效的,因为保证换行不会出现在新读取的文本行中。

修改:使用替换\(foo\|bar\)缩短命令

以前的版本:

    sed 's|([^)]*)|\n&\n|g;s|\n\((/\?s)\)\n|\1|g; s|\n\((VOCAL_NOISE)\)\n|\1|g;s|\n\(([^)]*)\)\n|~NS|g' inputfile

答案 2 :(得分:0)

我可以使用vim建议:

:%s/\((\w\+)\)\&\(\((s)\|(VOCAL_NOISE)\)\@!\)/\~NS/g

使用shell(bash),您可以执行以下操作:

vim file -c '%s/\((\w\+)\)\&\(\((s)\|(VOCAL_NOISE)\)\@!\)/\~NS/g' -c "wq"

首先进行备份,如果错误,我不对任何损害负责。

答案 3 :(得分:0)

只是这个?

sed -E 's/\((VOCAL_N|UNKNOWN)\)/~NS/'

在这种情况下,你有一个黑名单(你知道要过滤掉什么)。或者你绝对需要一个白名单(你知道什么不过滤掉)?

答案 4 :(得分:0)

awk -vRS=")" -vFS="(" '$2!~/s|\\s|VOCAL_NOISE/{$2="~NS"}RT' ORS=")"  file |sed 's/~NS)/~NS/g'