Bash脚本模式匹配

21

我需要找到一些特定的6位数模式,其中前3位是指定数字,而剩下的3位可以是任何数字。 例如,以123开头,后面跟着任意3个数字的6位数字符串。

var1="abc,123111,"
var2="abcdefg,123222,"
var3="xyzabc,987111,"

if [[ $var1 == *",123ddd,"* ]] ; then echo "Pattern matched"; fi

其中 ddd 代表任意数字。var1 和 var2 符合该模式,而 var3 不符合。我似乎无法得到完全正确的结果。

2个回答

29
使用字符类:[0-9] 匹配 09 和它们之间的每个字符,至少在 Unicode(例如 UTF-8)和子集字符集(例如 US-ASCII、Latin-1)中,它们是数字 18。因此,它匹配任何一个拉丁数字中的10个数字之一。
if [[ $var1 == *,123[0-9][0-9][0-9],* ]] ; then echo "Pattern matched"; fi

使用=~而不是==可以将模式类型从Shell标准的“glob”模式更改为正则表达式(简称“regexes”)。您可以使等效的正则表达式更短一些:

if [[ $var1 =~ ,123[0-9]{3}, ]] ; then echo "Pattern matched"; fi

第一处简化来自于 [[ =~ ]] 只需要正则表达式匹配字符串的任意部分,而不是整个字符串。因此,您不需要像在通配符模式中找到的前导和尾随的*等价物。
第二个长度缩短是由于 {n} 语法,它允许您指定前一个模式的重复次数,而不必在正则表达式中重复该模式本身。(您也可以通过指定最小值和最大值来匹配一系列重复计数:[0-9]{2,4} 将匹配连续的两个、三个或四个数字。)
值得注意的是,您还可以使用命名字符类来匹配数字。根据您的区域设置,[[:digit:]] 可能与 [0-9] 完全等效,或者它可能包括具有 Unicode“Number, Decimal Digit”属性的其他脚本的字符。
if [[ $var1 =~ ,123[[:digit:]]{3}, ]] ; then echo "Pattern matched"; fi

3
干得好。小问题:[0-9] 匹配 09 这个范围内的字符,取决于(有效的)LC_CTYPE 值(请参见 locale)。在现在普及的基于 UTF-8 的语言环境中,这与ASCII / Latin-1 字符 09 重叠,因为这些编码是 Unicode 的真正子集。相比之下,[[:digits:]] 不仅匹配 09,还可以匹配额外的 UTF-8 字符,基于 Unicode 标准认为是数字。 - mklement0

2

Bash 通配符匹配 [0-9] 可以用来匹配数字:

if [[ $var1 == *,123[0-9][0-9][0-9],* ]] ; then echo "Pattern matched"; fi

或者,你可以使用正则表达式模式匹配=~:

if [[ $var1 =~ .*,123[0-9]{3},.* ]] ; then echo "Pattern matched"; fi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接