正则表达式的字符串取反操作
文件同步时,想要过滤掉扩展名为.tmp或者.TMP的临时文件,想要使用正则表达式对字符串进行取反操作。
注意:[^tmp]* 这种取反的表达式,只能表示匹配除了t、m、p以外的所有字符,是单字符匹配,而不是字符串匹配取反。
正则表达式的字符串取反操作,可以使用正则的断言来实现。正则表达式的先行断言和后行断言有四种模式:
(?=pattern) 零宽正向先行断言(ero-width positive lookahead assertion),正向往后查找
(?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion),负向往前查找
(?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion),正向往后查找
(?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion),负向往前查找
这里面的 pattern 是一个正则表达式。
Java中正则表达式的字符串取反操作:
((?!你的正则表达式).)*
((?!你的正则表达式1|你的正则表达式2).)*
例如:Java中使用正则表达式排除扩展名为.tmp、.TMP临时文件,表达式如下:
^.*\.((?!tmp|TMP).)*$
说明:
表达式(?!tmp|TMP).会往前查找是不是没有"tmp"或者"TMP"字符串,如果没有(是其他字符),那么.就会匹配这些其他字符。这种表达式查找也叫零宽负向先行断言(zero-width negative lookahead assertion),它不会捕获任何字符、仅仅只是判断。
上面例子,针对每个字符都会检查前面的字符串是否不是"tmp"或者"TMP",如果不是,那么.就是匹配捕捉这个字符。表达式(?!tmop|TMP).只执行一次,所以,我们将该表达式用括号()包裹成组(group),然后用*修饰匹配0次或多次。
另外,关于正则表达式的元字符支持情况,不同的环境有差异:
其他常用正则表达式
Linux awk+正则:
[root@localhost opt]# find aaa
aaa
aaa/2023_xxx_03300.grib2
aaa/2023_xxx_03301.grib2
aaa/2023_xxx_03302.grib2.tmp
aaa/2023_xxx_03303.grib2.TMP
aaa/subdir01
aaa/subdir01/2023_xxx_04404.test
aaa/subdir01/2023_xxx_04400.grib2
aaa/subdir01/2023_xxx_04401.grib2
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/subdir01/2023_xxx_04403.grib2.TMP
aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.(tmp|TMP)$/{print}'
aaa/2023_xxx_03302.grib2.tmp
aaa/2023_xxx_03303.grib2.TMP
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/subdir01/2023_xxx_04403.grib2.TMP
[root@localhost opt]# find aaa | awk '/^.*\.(?:|tmp|TMP)$/{print}'
aaa/2023_xxx_03302.grib2.tmp
aaa/2023_xxx_03303.grib2.TMP
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/subdir01/2023_xxx_04403.grib2.TMP
[root@localhost opt]# find aaa | awk '/^.*\.t(est|mp)*$/{print}'
aaa/2023_xxx_03302.grib2.tmp
aaa/subdir01/2023_xxx_04404.test
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.t(?:|est|mp)*$/{print}'
aaa/2023_xxx_03302.grib2.tmp
aaa/subdir01/2023_xxx_04404.test
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.t(?:|est|mp)*$/'{print}
aaa/2023_xxx_03302.grib2.tmp
aaa/subdir01/2023_xxx_04404.test
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.t(?:|est|mp)*$/{print}'
aaa/2023_xxx_03302.grib2.tmp
aaa/subdir01/2023_xxx_04404.test
aaa/subdir01/2023_xxx_04402.grib2.tmp
aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.t(?:|est|mp)*$/{print NR,$0}'
4 aaa/2023_xxx_03302.grib2.tmp
7 aaa/subdir01/2023_xxx_04404.test
10 aaa/subdir01/2023_xxx_04402.grib2.tmp
12 aaa/2023_xxx_03304.test
[root@localhost opt]# find aaa | awk '/^.*\.t(?:|est|mp)*$/{print}' | awk '{print NR, $0}'
1 aaa/2023_xxx_03302.grib2.tmp
2 aaa/subdir01/2023_xxx_04404.test
3 aaa/subdir01/2023_xxx_04402.grib2.tmp
4 aaa/2023_xxx_03304.test
[root@localhost opt]# awk '/^.*\.t(?:|est|mp)*$/{print NR,$0}' a.txt
4 aaa/2023_xxx_03302.grib2.tmp
7 aaa/subdir01/2023_xxx_04404.test
10 aaa/subdir01/2023_xxx_04402.grib2.tmp
12 aaa/2023_xxx_03304.test
[root@localhost opt]#