正则expression式不能以给定的后缀结尾

我一直无法find一个正确的正则expression式来匹配任何以某种条件结束的string。 例如,我不想匹配以a结尾的任何内容。

这匹配

 b ab 1 

这不匹配

 a ba 

我知道正则expression式应该以$结束标记结束,虽然我不知道应该在什么前面。

编辑 :原来的问题似乎不是一个合法的例子,我的情况。 那么:如何处理多个angular色呢? 说什么不是以ab结尾?

我已经能够解决这个问题,使用这个线程 :

 .*(?:(?!ab).).$ 

虽然这个缺点是,它不匹配一个字符的string。

你不给我们的语言,但如果你的正则expression式风味支持后面的断言 ,这是你所需要的:

 .*(?<!a)$ 

(?<!a)是否定后置断言,确保在string(或带有m修饰符的行)结束之前,不存在字符“a”。

在Regexr上查看

你也可以很容易地用其他字符来扩展它,因为这个检查string并不是字符类。

 .*(?<!ab)$ 

这将匹配任何不以“ab”结尾, 在Regexr上查看

使用not^ )符号:

 .*[^a]$ 

如果将^符号放在括号的开头,则表示“除括号内的内容外的所有内容”。 $只是最终的锚点。

对于多个字符 ,只需将它们全部放入自己的字符集中即可:

 .*[^a][^b]$ 

要search不以“.tmp”结尾的文件,我们使用以下正则expression式:

 ^(?!.*[.]tmp$).*$ 

用正则expression式testing仪testing结果如下:

在这里输入图像说明

 .*[^a]$ 

上面的正则expression式将匹配不以a结尾的string。

尝试这个

 /.*[^a]$/ 

[]表示一个字符类,并且^反转字符类以匹配除了a所有内容。

任何匹配以。— .*a$结尾的东西所以,当你匹配正则expression式时,否定条件或者你也可以做.*[^a]$其中[^a]表示任何not a

问题是旧的,但我找不到更好的解决scheme,我发布在这里。 find所有的USB驱动器,但没有列出分区 ,从结果中删除“零件[0-9]”。 我结束了两个grep,最后否定了结果:

 ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$" 

这个结果在我的系统上:

 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 

如果我只想要我可以做的分区:

 ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$" 

我在哪里得到:

 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2 

而当我这样做:

 readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 

我得到:

 /dev/sdb 

如果你可以使用lookarounds,那么接受的答案是好的。 不过,还有另一种解决这个问题的方法。

如果我们看一下这个问题广泛提出的正则expression式:

.*[^a]$

我们会发现它几乎可行。 它不接受空string,这可能有点不方便。 但是,在处理一个字符时,这是一个小问题。 但是,如果我们要排除整个string,例如“abc”,那么:

.*[^a][^b][^c]$

不会的 例如,它不会接受交stream。

这个问题有一个简单的解决scheme。 我们可以简单地说:

.{,2}$|.*[^a][^b][^c]$

或更广义的版本:

.{,n-1}$|.*[^firstchar][^secondchar]$其中n是要禁止的string长度( abc为3), firstcharsecondchar ,…是第一个,第二个。你的string的第n个字符(对于abc它将是a ,然后b ,然后c )。

这来自一个简单的观察,即一个比我们不禁止的文本短的string不能按照定义包含这个文本。 所以我们可以接受任何短的(“ab”不是“abc”),或者任何足以让我们接受但没有结束的东西。

下面是一个查找的例子,它将删除所有不是.jpg的文件:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete