首页 > 解决方案 > Sed 模式没有替代预期的结果

问题描述

我正在尝试 sed 的黑客排名问题。我试图编写自己的解决方案,但没有奏效。我无法弄清楚为什么我的解决方案不起作用

示例问题:包含信用卡号的文件说“4321 5667 8765 1234”。我必须将此模式更改为“**** **** **** 1234”

我写的 Sed 模式是

sed 's/([0-9]{4}) ([0-9]{4}) ([0-9]{4}) ([0-9]{4})/**** **** **** \4/' sample_data 

它给出的输出为

4321 5667 8765 1234

It seems like sed is not matching pattern and that is the reason it is printing string as it is

我知道一些较小的解决方案,例如

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

这是有效的

我又试了

sed 's/[^ ]+ /****/g' # replaced with * with +

它不匹配任何模式。

标签: regexlinuxsed

解决方案


使用全局替换的稍短的选项可以写成:

sed -E 's/[0-9]{4}\s+/**** /g'

它使用扩展的正则表达式来匹配:

  • [0-9]{4}\s+数字{four of them}和至少一个空格;和
  • 将它们替换为"**** "

等效(但更长)的基本正则表达式是:

sed 's/[0-9][0-9][0-9][0-9]\s\s*/**** /g'

其中每个数字都明确列出并\s\s*匹配一个或多个空格并应用相同的替换。BRE 不支持{4}模式重复或+ERE 支持。

此外,由于hackerrank 很喜欢用极端情况来绊倒你你可能需要在处理数字之前修剪前导和尾随空格,例如

sed -e 's/^\s*//' -e 's/\s*$//' -e 's/[0-9][0-9][0-9][0-9]\s\s*/**** /g'

这样,您还可以处理以下行:

"  4321 5667 8765 1234  "

推荐阅读