【问题标题】:Multiple lazy string replacing between two patterns with sed使用 sed 在两个模式之间替换多个惰性字符串
【发布时间】:2016-03-22 13:40:37
【问题描述】:

例子:

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

我想要什么:

This is a test file.

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

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

我收到 This file 这是错误的。


如果我想替换两个相同模式之间的字符串呢?

喜欢:

WORD1 %WORD2% WORD3 => WORD1 WORD3

【问题讨论】:

  • 所以要删除括号内的所有文本?
  • 没错。但是括号只是一个非常简单的例子,它也可以是多个符号,例如#/to be replace/#或%to be replace%
  • 请更新问题以提供更多详细信息。
  • @Lobby2:同样,为什么相同的模式?相同的部分在哪里?你期望WORD1 %WORD2% WORD3 something WORD1 %WORD2% WORD3 的输出是什么?
  • 指定的副本也专门回答了该案例。请在此处发布之前查看现有问题。谢谢。

标签: regex bash shell sed


【解决方案1】:

您只需要一个否定字符类[^&lt;&gt;]*,它将匹配除&lt;&gt; 之外的任何字符:

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

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

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

IDEONE demo

至于更新,您可以使用.* 删除从WORD1WORD3 的所有内容,但仅当只有一组WORD1WORD3 (@ 987654322@):

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

对于,不能使用环视(此处为前瞻),也不能使用惰性量词将匹配限制在最左边的WORD3 出现。如果你确定中间没有% 符号,你仍然可以使用否定字符类方法(demo):

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

一个通用的解决方案是分几个步骤来做:

  • 将开始和结束分隔符替换为未使用的字符 (&lt;UC&gt;)(我使用的是俄语字母,但应该是一些控制字符)
  • 使用否定字符类&lt;UC1&gt;[^&lt;UC1&gt;&lt;UC2&gt;]*&lt;UC2&gt; 替换为必要的替换字符串
  • 恢复初始分隔符。

这是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

我正在硬编码一个空格,但可以随时调整它。

【讨论】:

  • 现在我有另一个问题:如果我想替换两个相同模式之间的字符串呢?喜欢 WORD1 %WORD2% WORD3 => WORD1 WORD3?
  • 如果您的意思是您知道WORD1WORD3 并且您需要将它们之间的所有内容都删除,那么这些就不一样了。也许你需要this
  • 这是一个很常见的问题。如果您没有时间寻找好的副本,请不要回答。
  • 您在正则表达式标签中有一个金色徽章。您的答案不包含环顾四周。
  • 如果您指的是OP的后续问题;不,我忽略了这一点。如果 OP 有新问题,他们应该发布新问题,或编辑当前问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2020-11-15
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多