248

我无法找到合适的正则表达式来匹配任何以某些条件结尾的字符串。例如,我不想匹配任何以a.

这匹配

b
ab
1

这不匹配

a
ba

我知道正则表达式应该$以标记结尾,但我不知道它之前应该是什么。

编辑:原始问题似乎不是我的案例的合法示例。那么:如何处理多个字符?说什么不以ab?

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

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

尽管这样做的缺点是,它不匹配一个字符的字符串。

4

9 回答 9

337

你没有给我们语言,但如果你的正则表达式支持在 assertion 后面,这就是你需要的:

.*(?<!a)$

(?<!a)是一个否定的lookbehind断言,它确保在字符串(或带有m修饰符的行)的结尾之前,没有字符“a”。

在 Regexr 上查看

您还可以使用其他字符轻松扩展它,因为它检查字符串而不是字符类。

.*(?<!ab)$

这将匹配不以“ab”结尾的任何内容,请参见 Regexr

于 2013-05-06T12:29:54.240 回答
96

使用( ^) 符号:

.*[^a]$

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

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

.*[^a][^b]$
于 2013-05-06T12:11:41.513 回答
64

要搜索不以“.tmp”结尾的文件,我们使用以下正则表达式:

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

用正则表达式测试器测试得到以下结果:

在此处输入图像描述

于 2015-11-23T10:24:06.120 回答
9
.*[^a]$

上面的正则表达式将匹配不以 . 结尾的字符串a

于 2013-05-06T12:12:14.297 回答
6

尝试这个

/.*[^a]$/

[]表示字符类,反转^字符类以匹配除a.

于 2013-05-06T12:12:38.970 回答
3

如果您可以使用环视,则接受的答案很好。但是,还有另一种方法可以解决这个问题。

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

.*[^a]$

我们会发现它几乎可以工作。它不接受空字符串,这可能有点不方便。然而,当只处理一个字符时,这是一个小问题。但是,如果我们想排除整个字符串,例如“abc”,那么:

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

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

不过,这个问题有一个简单的解决方案。我们可以简单地说:

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

或更通用的版本:

.{,n-1}$|.*[^firstchar][^secondchar]$ 其中 n 是您要禁止的字符串的长度(因为abc它是 3),并且firstchar, secondchar, ... 是字符串的第一个、第二个...第 n 个字符(因为abc它是a, then b, then c)。

这来自一个简单的观察,即比我们不会禁止的文本更短的字符串不能根据定义包含该文本。所以我们可以接受任何更短的东西(“ab”不是“abc”),或者任何足够长的东西让我们接受但没有结尾。

这是一个 find 示例,它将删除所有不是 .jpg 的文件:

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

于 2017-02-08T11:52:30.107 回答
1

这个问题很老,但我找不到更好的解决方案,我在这里发布了我的问题。查找所有 USB 驱动器但不列出分区,从而从结果中删除“part[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
于 2016-10-20T10:54:09.413 回答
0

任何与以 --- 结尾的东西匹配的东西,.*a$所以当你匹配正则表达式时,否定条件,或者你也可以做.*[^a]$where[^a]意味着任何not a

于 2013-05-06T12:12:36.183 回答
0

如果您正在使用grepsed语法会有所不同。请注意,顺序[^a][^b]方法在这里不起作用:

balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW,我在Regex101中找到了相同的结果,我认为这是 JavaScript 语法。

坏:https
://regex101.com/r/MJGAmX/2 好:https ://regex101.com/r/LzrIBu/2

于 2019-02-20T20:34:24.560 回答