正则表达式整理(BRE、ERE、PCRE)
学完正则表达式后,发现vscode的查找替换功能支持正则表达式,经常在vscode上实践,用得也越来越顺手,一度觉得自己的正则表达式玩的挺溜的。
但每每在grep
,find
,vim
这些工具中使用正则表达式时,却总有各种问题,在vscode上正常工作的正则表达式突然不起作用,甚至还给报错,不禁让人怀疑人生。直到今天才发现,这些差异是grep
等工具所支持的正则表达式与vscode不同引起的。
总的来说,正则表达式可以分为Basic Regular Expressions (BRE)
, Extended Regular Expressions (ERE)
, Perl Compatible Regular Expressions (PCRE)
三类,其中BRE
只支持基本的正则表达式,特殊规则需要使用转义符才能使用;ERE
在BRE
的基础上进行扩展,使用特殊规则时无需转义;PCRE
支持更多的特殊规则,比如d
,w
等。三者规则上的两个常见差异如下:
-
在
ERE
和PCRE
中,可以直接使用*, +, ?, (, ), {, }, |, .
这些字符,但在BRE
中,需要在前面加上转义符*, +, ?, (, ), {, }, |, .
; -
PCRE
支持d, w
等特殊规则,在ERE
和BRE
中需要用[0-9], [a-Z]
来完成;
举个具体的例子,提取文本中的11位数的电话号码,三种正则表达式对应的grep
命令分别为:
grep -P 'd{11}' phone_list.txt # PCRE
grep -E '[0-9]{11}' phone_list.txt # ERE
grep '[0-9]{11}' phone_list.txt # BRE
vscode上支持的是PCRE
,这是最便捷的一种正则表达式,用起来很方便。grep
,sed
等工具支持的默认方式是BRE
,所以当我按PCRE
的规则在grep
里写BRE
的正则表达式时,很可能由于使用的特殊规则不被支持而失效。这也是我在用grep
等工具感觉一团乱麻的原因。
grep
工具可以通过指定参数以支持不同的类别的正则表达式,比如通过指定-E
支持ERE
,通过指定-P
支持PCRE
。但sed
工具并不支持PCRE,只支持BRE
和ERE
。find
命令只支持ERE
,可以通过find -regex 'your_ere'
搜索当前文件夹的匹配文件
如果要更严谨一些,其实正则表达式不仅仅分为BRE
、ERE
、PCRE
,还分POSIX BRE
, POSIX ERE
, GUN BRE
, GUN ERE
等,甚至在不同的编程语言中也存在一些差异,上面只是一个大体的介绍。
例子——用sed获取记录中的某个分量的列表并排序
数据内容如下
scene=city_time_num[6], order=000, epoch_num=600, rate-lambda2-rho-alpha-threshold=25.000, 0.500, 0.00100, 0.020, 0.60000, epoch=600, iters=14, avg_psnr=35.411, 35.411, psnr=[33.153154166192095, 34.704279109335964, 37.78742808969121, 35.9988477316099] , avg_ssim=0.9787526391547257, ssim=[0.9487845528918274, 0.9728695331527001, 0.981355757416118, 0.9695059914677088, 1.0, 1.0], mse=4.60813E+02, 9.33541E-01, loss=1.16158E+04, cur_time2023-08-16 21:23:34
scene=city_time_num[6], order=100, epoch_num=600, rate-lambda2-rho-alpha-threshold=25.000, 0.500, 0.10000, 0.020, 0.60000, epoch=600, iters=15, avg_psnr=34.978, 34.978, psnr=[32.844886221882774, 34.20092499707755, 37.721248804834175, 35.145515735352554] , avg_ssim=0.9775971501470594, ssim=[0.9453385577641444, 0.9717984184514672, 0.980794551273793, 0.9676513733929512, 1.0, 1.0], mse=5.13529E+02, 9.33541E-01, loss=1.16236E+04, cur_time2023-08-16 21:56:18
scene=city_time_num[6], order=120, epoch_num=600, rate-lambda2-rho-alpha-threshold=25.000, 0.500, 0.00000, 0.020, 0.60000, epoch=600, iters=19, avg_psnr=34.675, 34.675, psnr=[32.74805443096332, 33.98555600184222, 37.08011284617032, 34.8855425424826] , avg_ssim=0.9768241752875638, ssim=[0.944663846905199, 0.9703824247208576, 0.9793499487053454, 0.9665488313939812, 1.0, 1.0], mse=5.29642E+02, 9.33541E-01, loss=1.17355E+04, cur_time2023-08-17 14:19:49
要提取的数据是avg_psnr
,先用sed命令清洗数据,然后用sort
命令排序:
$ sed -E 's/.+avg_psnr=([0-9]+.[0-9]+).+/1/' ./best_record.txt | sort -n
34.675
34.978
35.411
Reference
The Different Flavors of Regular Expressions
正则表达式“派别”简述
Regular Expression Engine Comparison Chart