正则反选子字符串
例子如下:
strip_all() {
# Usage: strip_all "string" "pattern"
printf '%s\n' "${1//$2}"
}
----------------------------------------------------------------------------------------------------------------------------------------------------
strip() {
# Usage: strip "string" "pattern"
printf '%s\n' "${1/$2}"
}
解析如下:
- ${parameter/pattern/string}
pattern 提供了一种匹配模式,parameter 中第一个匹配 pattern 的子串会被string 所替代,如果 pattern 以#
开头,parameter 中第一个匹配的子字符串以会被替换;如果 pattern以%
开头,parameter 中最后一个匹配的子字符串会被替换,如果 string 是null
,那么parameter 中匹配的子字符串会被删除,并且 string前的\
会被省略;另外,当parameter 使用了@
或者*
这样的特殊符号来代表一系列数据时,相当于每一个数据进行了匹配pattern 并被替换为string 的过程 - ${parameter//pattern/string}
与上面过程的区别在于,此模式下会对parameter 中所有匹配 pattern的子字符串进行替换
移除字符串中匹配正则表达式最左边内容
例子如下:
lstrip() {
# Usage: lstrip "string" "pattern"
printf '%s\n' "${1##$2}"
}
解析如下:
- ${parameter##word}
##
属于贪婪匹配,在parameter 从左向右找出匹配的最长结果,并删除所匹配的字符串
移除字符串匹配正则表达式最右边内容
例子如下:
rstrip() {
# Usage: rstrip "string" "pattern"
printf '%s\n' "${1%%$2}"
}
解析如下:
- ${parameter%%word}
和上面的例子类似,%%
属于贪婪匹配,在parameter 从右向左找出匹配的最长结果,并删除所匹配的字符串
字符串转换为URL编码
例子如下:
urlencode() {
# Usage: urlencode "string"
local LC_ALL=C
for (( i = 0; i < ${#1}; i++ )); do
: "${1:i:1}"
case "$_" in
[a-zA-Z0-9.~_-])
printf '%s' "$_"
;;
*)
printf '%%%02X' "'$_"
;;
esac
done
printf '\n'
}
解析如下:
local LC_ALL=C
可以参考LC_ALL=C的含义,这里仅仅点明一下,LC_ALL=C 是为了去除所有本地化的设置,让命令能正确执行${#1}
这个表达式代表获取${1}
的长度,当${1}
是字符串的时候,${#1}
是字符串的长度,当${1}
是数组或者类似$@、$*
这样的表达式时,${#1}
代表组成元素的数量:
和$_
解析可以参考上一篇文章的内容pure-bash-1,在这里$_
代表着上一行${1:i:1}
在每一次循环的结果printf '%%%02X' "'$_"
表示的内容是%XX
,XX表示大写的16进制的表示
URL编码转换普通字符串
例子如下:
urldecode() {
# Usage: urldecode "string"
: "${1//+/ }"
printf '%b\n' "${_//%/\\x}"
}
解析如下:
printf '%b\n' "${_//%/\\x}"
这里有两个注意的地方,${_//%/\\x}"
表示将%HH
转换为\xHH
,printf '%b\n'
会解析所有的转义字符,如\n
解析为换行符,而\xHH
会解析为对应的字符串
判断字符串中是否包含某一子串
使用if-else以及逻辑运算符
if [[ $var == *sub_string* ]]; then
printf '%s\n' "sub_string is in var."
fi
# Inverse (substring not in string).
if [[ $var != *sub_string* ]]; then
printf '%s\n' "sub_string is not in var."
fi
# This works for arrays too!
if [[ ${arr[*]} == *sub_string* ]]; then
printf '%s\n' "sub_string is in array."
fi
使用case关键字
case "$var" in
*sub_string*)
# Do stuff
;;
*sub_string2*)
# Do more stuff
;;
*)
# Else
;;
esac
解析如下:
- 当
==
或者!=
这样的运算符被使用时,运算符右边的表达式会根据 shell 正则表达式规则进行解析,当运算符左边的字符串能与运算符右边的表达式匹配(==
)或者不匹配(!=
)时,表达式返回结果是0
,反之返回结果是1
判断字符串是否以某一子串开头
例子如下:
if [[ $var == sub_string* ]]; then
printf '%s\n' "var starts with sub_string."
fi
# Inverse (var does not start with sub_string).
if [[ $var != sub_string* ]]; then
printf '%s\n' "var does not start with sub_string."
fi
判断字符串是否以某一子串结尾
if [[ $var == sub_string* ]]; then
printf '%s\n' "var starts with sub_string."
fi
# Inverse (var does not start with sub_string).
if [[ $var != sub_string* ]]; then
printf '%s\n' "var does not start with sub_string."
fi