如何替換變數中的子字串?

如何替換變數中的子字串?

我正在嘗試從字串變數中刪除字元。它對我來說是sed這樣的:

MYVAR=--23ho02123ware38384you443d34o3434ingtod38384day-%§*#sfrf
echo ${MYVAR} | sed -e 's/[a-z][a-z0-9\-]*//g'

我得到:

 --23%§*#

這就是我正在尋找的。字串應以字母開頭,並且僅包含字母、數字和破折號 (-)。有沒有辦法透過bash字串替換來實現這一點?

MYVAR=${MYVAR/[a-z][a-z0-9-]*/ }

我嘗試了幾種組合,但沒有一個可以按我的預期工作。

答案1

您需要使用 ksh 擴充 glob 運算子(其中的子集在bashwithshopt -s extglob和 with zshwith中可用set -o kshglob)來取得正規表示式的等效項(儘管使用不同的語法:*(x)對於此處的等效項x*):

shopt -s extglob # for bash
# set -o kshglob # for zsh
printf '%s\n' "${MYVAR//[[:alpha:]]*([[:alnum:]-])/}"

或使用zsh extendedglobs ,其中 regexp 的等效項*#

set -o extendedglob
printf '%s\n' ${MYVAR//[[:alpha:]][[:alnum:]-]#}

一些注意事項:

  • ${var/pattern/replacement}僅替換第一次出現的情況。用於${var//pattern/replacement}替換每個出現的地方(就像's命令g中的標誌一樣)。seds
  • 您已將替換字元設為空格。使用${var//pattern/}(或${var//pattern}) 替換為空字串。
  • 您不想用來echo輸出任意字串
  • 除了在zsh,列表上下文中的變數擴充必須被引用
  • sed當變數包含換行符號時,行為會與您的方法不同。
  • [a-z]a匹配由和組成的字元(在某些工具中整理元素)z,其列表隨語言環境、系統和工具的不同而變化(例如,GNU 系統上的語言環境中的[a-z]與、、、匹配,但不匹配) 。一般包括英文字母表中的 26 個小寫字母,但也不一定。包括被考慮的字元(或整理元素)bash-4.3en_GB.UTF-8AXéZ[[:alpha:]]按字母順序排列的(無論大小寫)在您的語言環境中。如果您只想配對 26 個英文字母,請使用[abcdefghijklmnopqrstuvwxyz]或將區域設定固定為C( LC_ALL=C),並僅使用[a-z][[:lower:]]表示小寫英文字母,或使用[a-zA-Z]/[[:alpha:]]表示任何英文字母。
  • [a-z0-9\-]insed確實匹配反斜線字符,請[a-z0-9-]改為使用(-必須是第一個或最後一個才能按字面意思理解)。

相關內容