首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用sed保持替换词的多元性和大写化

使用sed保持替换词的多元性和大写化
EN

Stack Overflow用户
提问于 2015-04-08 22:28:53
回答 3查看 150关注 0票数 3

我意识到标题是可怕的,但无论如何,我有一个任务,把所有的实例“猫”改为“狗”使用sed。很简单,但它也包括“弹射器”和“熊猫”这样的词,我试图通过在代码中添加一个空格来避免它们。我的问题是,每个词都变成“狗”,在某些情况下,我希望它是“狗”或“狗”.

下面是我要更改的文本文件:

亲爱的房主, 猫对人很重要。我们都喜欢猫的陪伴。如果你想养一只猫,我们可以帮忙。我们正试图为我们的城市举办一个“猫回家”的日子。为了帮助我们,我们已经征集了NWMSU的熊啦啦队长,这个城市一年一度的弹射器投掷的组织者,和当地的名人帮助为猫寻找家。 有一只猫需要你为它们提供一个家。所以,如果你是一个爱猫的人,请过来看看有没有办法在你的心里找到一个猫的家。 谢谢!! 猫也是人。

这是我得到的输出,这显然是错误的

亲爱的房主, 狗对人很重要。我们都喜欢猫的陪伴。如果你想养一只猫,我们可以帮忙。我们正试图为我们的城市举办一个“猫回家”的日子。为了帮助我们,我们已经征集了NWMSU的熊啦啦队长,这个城市一年一度的弹射器投掷的组织者,和当地的名人帮助为猫寻找家。 有一只猫需要你为它们提供一个家。所以,如果你是一个爱猫的人,请过来看看有没有办法在你的心里找到一个猫的家。 谢谢!! 狗也是人。

这是我的密码:

代码语言:javascript
复制
sed 's/[Cc]at[s] /dog /g' cats-dogs.txt 
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-08 22:47:56

我很肯定,你不能单用一个RegEx就能做到这一点。

尽管如此,简单的解决方案在这里可能是最好的,因为只有两种可能的情况(上和下)和一个替换词,它似乎(同时sed允许多个替换容易)。

因此,这样的东西应该可以工作(假设GNU ):

代码语言:javascript
复制
sed -r 's/\bCat(s?)\b/Dog\1/g; s/\bcat(s?)\b/dog\1/g' cats-dogs.txt

使用扩展的regexp,因为在命令行上引用并不那么可怕。请注意这里的字词边界扫描。

可能有一种非常聪明(且不可读)的sed方法可以使用\u和缓冲区来实现这一点。

票数 3
EN

Stack Overflow用户

发布于 2015-04-08 22:57:39

到目前为止,让我们分析一下您的尝试。

代码语言:javascript
复制
s/[Cc]at[s] /dog /g

这将搜索regex [Cc]at[s]并替换dog。有几个原因不起作用..。

  • 它未能为第一个字母保持大写。
  • 第二个范围,[s]的意思是“字母s”。

如果您正在使用Linux,那么在您的系统上安装的sed版本可能是GNU,下面的内容可能有效:

代码语言:javascript
复制
sed -r 's/\bcat(s?)\b/dog\1/g;s/\bCat(s?)\b/Dog\1/g'

注意-r选项,它告诉sed使用“扩展”正则表达式表示法,而不是默认的“基本”表示法。

此解决方案依赖sed对\b单词边界的理解,但需要注意的是,在其他操作系统(FreeBSD、OSX、Solaris等)上的sed实现中并不普遍可用这一缩写。如果可移植性很重要,请避免使用\b和类似的东西。

这个速记很好,但真的不需要。在BRE中也有一样的东西:

代码语言:javascript
复制
sed 's/[[:<:]]cat\(s*\)[[:>:]]/dog\1/g;s/[[:<:]]Cat\(s*\)[[:>:]]/Dog\1/g'

这是BRE而不是ERE,所以我们不使用-r选项。我应该指出,这也将与"catssss“相匹配,因为我们使用的是s*而不是s?。许多sed实现中的BRE并不包括只识别一个原子的一种方法。

传统的类[[:<:]][[:>:]]适用于单词的开头或结尾,有时比GNU的“单词边界”更好,后者可以用于单词的开头或结尾。

在任何带有man re_format的unix上都可以看到非GNU格式。

(注意到:sed的-r选项也不是通用的。在OSX中,使用-E代替。这是因为OSX的sed是从较早版本的FreeBSD派生而来的,后者仅在几个版本之前添加了-r作为-E的等效选项。)

票数 3
EN

Stack Overflow用户

发布于 2015-04-09 01:16:26

使用perl,但它并不漂亮:

代码语言:javascript
复制
perl -pe 's/\b(c)at(?=s?\b)/ $1 =~ m{[[:upper:]]} ? "Dog" : "dog" /ige' <<END
scat cat cats Cats Cat Catskills 
END

输出

代码语言:javascript
复制
scat dog dogs Dogs Dog Catskills 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29526457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档