如何从变量中替换子字符串?

din*_*ngs 7 bash string

我正在尝试从字符串变量中删除字符。它对我来说sed是这样的:

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

我得到:

 --23%§*#
Run Code Online (Sandbox Code Playgroud)

这就是我要找的。该字符串应以字母开头,并且仅包含字母、数字和破折号 (-)。有没有办法通过bash字符串替换来实现这一点?

MYVAR=${MYVAR/[a-z][a-z0-9-]*/ }
Run Code Online (Sandbox Code Playgroud)

我尝试了几种组合,但没有一个像我预期的那样工作。

Sté*_*las 10

您需要使用 ksh 扩展的 glob 运算符(其中的一个子集在bashwithshopt -s extglob和 with 中zsh可用set -o kshglob)来获得正则表达式的等效项(尽管使用不同的语法:*(x)对于等效项x*here):

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

或者使用zsh extendedglobs 相当于 regexp*#

set -o extendedglob
printf '%s\n' ${MYVAR//[[:alpha:]][[:alnum:]-]#}
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

  • ${var/pattern/replacement}仅替换第一次出现。使用${var//pattern/replacement}替换所有出现(如用g在标志seds指令)。
  • 您已将替换字符设置为空格字符。使用${var//pattern/}(或${var//pattern}) 替换为空字符串。
  • 你不想echo用来输出任意字符串
  • 除了 in zsh必须引用列表上下文中的变量扩展
  • sed当变量包含换行符时,与您的方法相比,行为会有所不同。
  • [a-z]包括之间的匹配字符(整理一些工具元素)az中,列表,它与区域设置,系统和工具的变化(例如[a-z]bash-4.3en_GB.UTF-8语言环境上的GNU系统相匹配AXé?,但没有Z)。这通常包括英文字母表中的 26 个小写字母,但不一定。[[:alpha:]]包括在您的语言环境中被视为字母(不分大小写)的字符(或整理元素)。如果您只想匹配 26 个英文字母,请使用[abcdefghijklmnopqrstuvwxyz]或将区域设置固定为C( LC_ALL=C) 并使用[a-z][[:lower:]]仅用于小写英文字母或[a-zA-Z]/[[:alpha:]] 对于任何英文字母。
  • [a-z0-9\-]insed确实与反斜杠字符匹配,请[a-z0-9-]改用(-必须是第一个或最后一个才能按字面意思使用)。