我有一个字符串,例如“something_something_something”
现在字符串必须具有以下模式:^[a-zA-Z0-9](-*[a-zA-Z0-9])*
如何替换字符串中与模式不匹配的所有字符?
对于我的例子,我应该:
somethingsomethingsomething
我尝试过sed -n '/^[a-zA-Z0-9](-*[a-zA-Z0-9])*/p'
,但没有成功。
答案1
其一,您需要sed -E
,以便将模式解释为扩展正则表达式 (ERE),并且普通括号用于分组。默认情况下,sed 的模式是基本正则表达式 (BRE),您需要使用\(
和\)
。
其次,sed -n '/.../p'
可以工作,但如果部分匹配,当然会打印整行。如果您的图案也固定在末尾,那么删除整行将会很有用。
如果你想删除不符合模式的部分,你可以这样做:
sed -E -e 's/^([a-zA-Z0-9](-*[a-zA-Z0-9])*).*/\1/' input.txt
尾随.*
确保整行匹配,然后所有内容都将替换为第一个捕获组中的内容。对于输入something_something_something
,这将打印something
,因为_
与模式的主要部分不匹配。
请注意,您的模式看起来等同于[-a-zA-Z0-9]+
.也许你的意思是类似的东西[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*
?这应该匹配像foo
or 这样的字符串foo-bar-doodoo
(但不是foo--bar
)。
答案2
我们编写另一个正则表达式,存储在名为 sNr(搜索 n 替换)的 shell 变量中,我们在其中添加您引用的某些正则表达式。
我们将把任何非某些字符替换为哈希值 (#)。
sNr='
s@
\(
\(
\(
[a-zA-Z0-9](-*[a-zA-Z0-9])*
\)\{1,\}
#*
\)*
\)
[^a-zA-Z0-9#]
@\1#@
';
echo something_something_something |
sed -e "
:loop
${sNr//[$IFS]/}
tloop
"
something#something#something