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 操作符有什么遗漏吗=~
?这与贪婪与非贪婪迭代器 ( ) 有关系吗[^.]+
?
有几种不同类型的正则表达式,每种类型都添加更多运算符(因此如果要将它们视为文字,则需要转义更多字符)。
\n操作=~
员在文档中进行了描述(请参阅man bash
您的系统或在线),如下所示,
\n\n另外还有一个二元运算符 ,
\n=~
可用,其优先级与==
和相同!=
。使用时,运算符右侧的字符串被视为POSIX 扩展正则表达式并进行相应匹配
grep -E
扩展正则表达式 (ERE) 可以与(以前的)匹配egrep
。您的示例是 Perl 兼容正则表达式 (PCRE),它是 ERE 的超集,不能与=~
. 但是,可以通过替换为进行简单\\d
调整[[:digit:]]
:
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
相当于=~
我们可以这样写,
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
:
^[^-.]+-[[:digit:]]{1,5}\\.csv$\n
Run Code Online (Sandbox Code Playgroud)\n如果您绝对决定使用 PCRE 而不是 ERE,您将必须使用外部工具,例如 GNU 实现grep
来执行匹配。但这效率较低,并且与上面给出的有关边界的相同建议也适用于此处:
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
尽可能多的字符,第二个将匹配尽可能少的字符。
括号( \xe2\x80\xa6 )
是分组,而不是贪婪指标。