
我是正規表示式和 sed 的新手,並且正在嘗試創建一個我認為簡單的正則表達式:我想刪除單字結尾的字母(如果它是“o”)。
- 輸入字串:你好你好
- 預期輸出:地獄地獄
好消息:當“o”位於字串末尾時,我可以將其刪除:
$ echo 'Hello Hello' |sed 's/\(.*\)o/\1/g'
Hello Hell
$ echo 'Hello Hello' |sed 's/\(.*\)o$/\1/g'
Hello Hell
壞消息:我無法將其從字串前面的單字中刪除。我已經嘗試過使用我能想到的所有錨符號。結果是詞尾的「o」都沒有刪除:
$ echo 'Hello Hello' |sed 's/\(.*\)o\b/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\>/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\W/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\s/\1/g'
Hello Hello
你能告訴我我做錯了什麼來幫助我恢復理智嗎?
更新:我的明顯印像是我的機器產生的結果與其他人的結果不同。我正在 Macbook 上使用終端機視窗。如果有人能解釋這一點,請告訴我。
答案1
echo 'Hello Hello' | sed 's/o$//'
對我來說似乎比你的更有用
echo 'Hello Hello' | sed 's/\(.*\)o$/\1/g'
你的問題是說輸出
echo 'Hello Hello' | sed 's/\(.*\)o\b/\1/g'
是Hello Hello
,但對我來說卻是Hello Hell
。您可以將其更正為
echo 'Hello Hello' | sed 's/\([^o]*\)o\b/\1/g'
但
echo 'Hello Hello' | sed 's/o\b//g'
對我來說似乎更好。
答案2
刪除o
單字末尾的 the 就是刪除單字字元和非單字字元(或 EOL)之間的 ao,因此:
sed -r 's/(\w)o(\W|$)/\1\2/g'
答案3
我想知道是否space
不是你的單字分隔符號。嘗試如下操作:
$ echo hello hello | sed -e 's/o / /g;s/o$//'
hell hell
此範例的問題在於,您還必須對.
and,
以及任何其他單字分隔符號執行相同的操作。匹配o
後跟另一個特定字符,如[]
like o[ \.,]
。由於某種原因,這不適用於 EOL $
,因此請使用 . 新增另一個搜尋字串;
。例子:
$ echo hello hello, hello. toot hello | sed -e 's/o\([ \.,]\)/\1/g;s/o$//'
hell hell, hell. toot hell
$ echo $SHELL
/bin/bash
$ sed --version
sed (GNU sed) 4.4
$ set | grep IFS
IFS=$' \t\n'
答案4
我已經嘗試過使用我能想到的所有錨符號。
這不是錨點,而是您與星號進行貪婪匹配的事實。表達式\(.*\)o
匹配盡可能長的字串,所以它會吃掉所有東西最後的 o
。它o
也可能與先前的匹配。
但是,捕獲一些東西然後將其返回是沒有用的,你可以完全刪除\(.*\)
和\1
。
因此,這些將(至少在 GNU sed 中)刪除o
單字末尾的 :
sed 's/o\>//g'
sed 's/o\b//g'
當然,這僅在字串末尾:
sed 's/o$//g'
這將刪除o
, 以及以下非單字字元(例如 後面的空格Hello
):
sed 's/o\W//g'
如果您sed
不支持\<
/\>
或\b
,您將不得不做其他事情。這將匹配o
後跟非字母數字字元或行尾:
$ echo "jello, jello" | sed -E -e 's/o([^[:alnum:]]|$)/\1/g'
jell, jell
sed
例如,這適用於OS X/macOS 隨附的作業系統。
Perl 正規表示式支援添加問號*
或+
使其成為非貪婪的。然後他們會匹配最短可能的字串:
echo "jello, jello" | perl -pe 's/(.*?)o/$1/g'
jell, jell