bash
目前大部分shell(如bash)都提供了正则表达式判断操作符=~,如下就可以对一个字符符判断是否匹配正则表达式:
$ [[ "hello world" =~ wor(ld)? ]] && echo matched
matched
其实基于上面的表达式不仅可以判断是否匹配正则表达,还可以通过上面表达式创建的变量 BASH_REMATCH(数组)提取捕获组(catch group),
如下提取一个url的protocol和host部分
$ [[ "http://www.baidu.com" =~ (https?)://([[:alnum:]]+(\.[[:alnum:]_]+)*) ]] \
&& echo ${BASH_REMATCH[1]} ${BASH_REMATCH[2]}
http www.baidu.com
${BASH_REMATCH[0]} 即正则表达式的捕获组0(全部字符串)
${BASH_REMATCH[1]} 即正则表达式的捕获组1,以此类推
BASH_REMATCH 是 bash定义的保存正则表达式捕获组的变量,不同的脚本解释有不同的定义,比如zsh,ksh就有另外的变量定义方式
ksh
保存正则表达匹配数据的数组变量名叫 .sh.match ,对BASH_REMATCH,引用时必须以${.sh.match}方式引用
${.sh.match[0]} 即正则表达式的捕获组0(全部字符串)
${.sh.match[1]} 即正则表达式的捕获组1,以此类推
zsh
$MATCH 保存匹配的整个字符串,对应就是bash的BASH_REMATCH[0]
$match保存捕获组数据的数组(索引从1开始),$match[1]就对应BASH_REMATCH[1]
通用的实现
根据上面不同shell的实现试可以合成实现一个通用函数来以抹平shell之间的差异
function reMatch {
typeset ec
unset -v reMatch # initialize output variable
[[ $1 =~ $2 ]] # perform the regex test
ec=$? # save exit code
if [[ $ec -eq 0 ]]; then # copy result to output variable
[[ -n $BASH_VERSION ]] && reMatch=( "${BASH_REMATCH[@]}" )
[[ -n $KSH_VERSION ]] && reMatch=( "${.sh.match[@]}" )
[[ -n $ZSH_VERSION ]] && reMatch=( "$MATCH" "${match[@]}" )
fi
return $ec
}
调用示例:
$ reMatch "http://www.baidu.com" "(https?)://([[:alnum:]]+(\.[[:alnum:]_]+)*)"
$ echo ${reMatch[1]} ${reMatch[2]}
http www.baidu.com
更详细的说明参见参考资料1

本文介绍了如何在Bash、Ksh和Zsh等Shell环境中使用正则表达式进行字符串匹配,并展示了如何提取捕获组。通过示例展示了`BASH_REMATCH`、`.sh.match`和`MATCH`变量在不同Shell中的应用,以及如何编写一个通用函数`reMatch`来统一这些差异。此外,还提供了不同Shell中获取匹配结果的详细说明。
443

被折叠的 条评论
为什么被折叠?



