几天来我一直在努力尝试让一些看似简单的事情发挥作用。
(LC_ALL=POSIX; regex="src\\.[\\x20-\\x7E]+\\.system"; file="src.dirtree.system";
if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
我们的愿望是匹配 src.*.system,其中 * 可以是字符范围内的任何内容\x21-\x7E
。如果我想要\x20-\x7E
那么[ -~]+
可以工作,但是我怎样才能让这个范围工作或任何带有重复的任意十六进制转义范围*, + or {x,y}
?
Bash 版本是4.3.11(1)-release
,不,我无法更改它。
答案1
man 3 regex
详细信息请参阅 Bash 文档:
还可以使用附加二元运算符“
=~
”,其优先级与“==
”和“!=
”相同。使用时,运算符右侧的字符串被视为扩展正则表达式并进行相应的匹配(如正则表达式3))。
man 3 regex
在 Linux 上表明这些是 POSIX 正则表达式,这由以下描述证实配置标志需要启用此功能:
--enable-cond-regexp
支持=~
在条件命令中使用“ ”二元运算符来匹配 POSIX 正则表达式[[
。 (看 条件结构)。
并且man 7 regex
描述了语法,表示:
除了这些字符和某些使用“[”的组合(参见下一段)之外,所有其他特殊字符(包括“\”)在方括号表达式中都会失去其特殊意义。
并且没有提及十六进制字节范围。所以我想说这不是直接可能的。
你可以滥用ANSI C 引用功能用十六进制版本替换实际字节:
$ (LC_ALL=POSIX; regex="src\.["$'\x21-\x7E'"]+\.system"; file='src.dir!ree.system'; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
yes
$ (LC_ALL=POSIX; regex="src\.["$'\x21-\x7E'"]+\.system"; file='src.dir ree.system'; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
no
$ (LC_ALL=POSIX; regex="src\.["$'\x21-\x7E'"]+\.system"; file="src.dirtree.system"; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
yes
请注意regex
三个字符串的连接方式:"src\."
, $'\x21-\x7E'
(扩展为相应的字节)和"]+\.system"
。
当然,对于这种情况,您可以使用!-~
正确引用的 :
$ (LC_ALL=POSIX; regex='src\.[!-~]+\.system'; file='src.dirtree.system'; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
yes
$ (LC_ALL=POSIX; regex='src\.[!-~]+\.system'; file='src.dir!ree.system'; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
yes
$ (LC_ALL=POSIX; regex='src\.[!-~]+\.system'; file='src.dir ree.system'; if [[ $file =~ $regex ]]; then echo "yes"; else echo "no"; fi;)
no
或者[[:graph:]]
,我认为这应该与 ASCII 字符的范围相同。