字符串数字正则表达式替换

字符串数字正则表达式替换

我在这个替换正则表达式上遇到了一些困难,我无法理解为什么它会这样。我想要做的是替换最后一个之后的所有数字/

str="aa/a0b0/42"
echo ${str/%[[:digit:]]*/5}
echo ${str/%[0-9]*/5}

两者都作为输出echo产生。aa/a5预期输出为aa/a0b0/5.

我很清楚我可以使用sed和等工具awk来解决我的问题,并且我确实知道如何做到这一点,但我正在寻找仅 bash 的解决方案。

我想了解为什么[0-9]*扩展为 0b0/42 而不仅仅是数字。

我的正则表达式中的内容%后端更换

答案1

因为那是一个模式匹配,不是正则表达式。

[[:digit:]]*表示一位数字后跟任何字符串,这就是0b0/42匹配的原因。它是一位数字,0,后跟一个字符串,b0/42

现在,在 中bashextglob启用后,您可以使用 来+(pattern-list)匹配模式的一次或多次出现:

$ shopt -s extglob
$ printf '%s\n' "${str/%+([[:digit:]])/5}"
aa/a0b0/5

默认情况下,您在 中具有该语法ksh,该语法是bash从 复制的。

在 中zsh,虽然您可以将这些ksh模式与setopt kshglob或使用zsh自己的extendedglob( [[:digit:]]##),但您也可以使用以下命令执行正则表达式替换正则表达式替换 功能:

$ str="aa/a0b0/42"
$ autoload -U regexp-replace
$ regexp-replace str '[[:digit:]]+$' 5
$ print -rl -- $str
aa/a0b0/5

如果你确保最后一个后面的部分/总是数字,你可以用 POSIXly 来做到这一点:

printf '%s/%s\n' "${str%/*}" 5

相关内容