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

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

我正在尝试从字符串变量中删除字符。它对我来说是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-]改为使用(-必须是第一个或最后一个才能按字面意思理解)。

相关内容