Bash [[ test =~ regex ]] 与 perl 命令结果

rel*_*pec 3 bash regex perl bash-scripting

bash 运算符=~相当于perl调用吗?

filename="test-33.csv"
regex="([^.]+)(-\d{1,5})(\.csv)"
Run Code Online (Sandbox Code Playgroud)

通过 bash 测试:

filename="test-33.csv"
regex="([^.]+)(-\d{1,5})(\.csv)"
Run Code Online (Sandbox Code Playgroud)

perl

if [[ "$filename" =~ $regex ]]; then echo "it matches"; else echo "doesn't match"; fi
# doesn't match

if [[ "$filename" =~ ([^.]+)(-\d{1,5})(\.csv) ]]; then echo "matches"; else echo "doesn't match"; fi
# doesn't match
Run Code Online (Sandbox Code Playgroud)

我对 bash 操作符有什么遗漏吗=~?这与贪婪与非贪婪迭代器 ( ) 有关系吗[^.]+

roa*_*ima 8

有几种不同类型的正则表达式,每种类型都添加更多运算符(因此如果要将它们视为文字,则需要转义更多字符)。

\n

操作=~员在文档中进行了描述(请参阅man bash您的系统或在线),如下所示,

\n
\n

另外还有一个二元运算符 ,=~可用,其优先级与==和相同!=。使用时,运算符右侧的字符串被视为POSIX 扩展正则表达式并进行相应匹配

\n
\n

grep -E扩展正则表达式 (ERE) 可以与(以前的)匹配egrep。您的示例是 Perl 兼容正则表达式 (PCRE),它是 ERE 的超集,不能与=~. 但是,可以通过替换为进行简单\\d调整[[:digit:]]

\n
echo abc-123.csv | grep -E \'([^.]+)(-\\d{1,5})(\\.csv)\'             # ERE fails\necho abc-123.csv | grep -P \'([^.]+)(-\\d{1,5})(\\.csv)\'             # PCRE matches with GNU grep\n\necho abc-123.csv | grep -E \'([^.]+)(-[[:digit:]]{1,5})(\\.csv)\'    # ERE matches modified expression\n
Run Code Online (Sandbox Code Playgroud)\n

因此,鉴于这grep -E相当于=~我们可以这样写,

\n
if [[ "$filename" =~ ([^.]+)(-[[:digit:]]{1,5})(\\.csv) ]]\nthen\n    echo "matches"\nelse\n    echo "doesn\'t match"\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,您的 ERE 可能应该以 为前缀^和后缀$,并[^.]+调整为[^-.]+以确保您不能匹配诸如 之类的字符串abc-def-12345678-123.csv.txt

\n
^[^-.]+-[[:digit:]]{1,5}\\.csv$\n
Run Code Online (Sandbox Code Playgroud)\n

如果您绝对决定使用 PCRE 而不是 ERE,您将必须使用外部工具,例如 GNU 实现grep来执行匹配。但这效率较低,并且与上面给出的有关边界的相同建议也适用于此处:

\n
if echo "$filename" | grep -qP \'([^.]+)(-\\d{1,5})(\\.csv)\'\nthen\n    echo "matches"\nelse\n    echo "doesn\'t match"\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

基本 RE(RE 或 BRE)和 ERE 的 POSIX 参考位于https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html,Perl RE (PCRE) 的参考位于https:// www.pcre.org/original/doc/html/pcrepattern.html。请注意,这两种文档都不是最容易理解的。

\n

最后你问,

\n
\n

这与贪婪与非贪婪迭代器有关吗([^.]+)

\n
\n

那不是贪婪/非贪婪迭代器。[^.]+是贪婪的,意味着“除了点 ( .)之外的一个或多个”。ERE 没有非贪婪运算符。PCRE 可以定义非贪婪运算符,例如*+通过在其后面添加?。例如对比度a*a*?;第一个将匹配a尽可能多的字符,第二个将匹配尽可能少的字符。

\n

括号( \xe2\x80\xa6 )是分组,而不是贪婪指标。

\n

  • @ilkkachu 是的,我知道,但我正在努力让一个复杂的主题尽可能简单 (2认同)