字符串的正则表达式不以给定的后缀结尾

Posted

技术标签:

【中文标题】字符串的正则表达式不以给定的后缀结尾【英文标题】:Regex for string not ending with given suffix 【发布时间】:2013-04-30 04:36:50 【问题描述】:

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

这匹配

b
ab
1

这不匹配

a
ba

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

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

我已经能够解决这个问题,使用 this thread:

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

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

【问题讨论】:

【参考方案1】:

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

.*(?<!a)$

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

看here on Regexr

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

.*(?<!ab)$

这将匹配任何不以“ab”结尾的东西,see it on Regexr

【讨论】:

我不知道 RegexPAL,但正则表达式在所有语言中都不同,并且后向断言是一项并非所有人都支持的高级功能。 regexpal 是一个基于 javascript 的正则表达式测试器,而 javascript 不支持后向断言,这很可悲 正则表达式 (javascript) 不支持 Lookbehinds 在 JS 中缺乏回顾让我哭了。如果您正在做服务器端,尽管您可能可以在 NPM 上使用 PCRE 模块或类似的模块直接使用它们(这是一组绑定,所以我认为您不能在前端使用它) 更多类型的前瞻/后瞻断言:***.com/q/2973436/12484【参考方案2】:

使用 not (^) 符号:

.*[^a]$

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

For multiple characters,把它们都放在自己的字符集中:

.*[^a][^b]$

【讨论】:

+1,需要注意的是这与空字符串不匹配(可能与预期不同),因此其含义是“任何不在括号中的字符”。 @0A0D: 包含空格的字符串不是空字符串。 @0A0D 其实这没什么好争论的,这是事实 @Doorknob:这与 aecb 不匹配。 不,这也不允许“acb”。【参考方案3】:

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

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

用Regex Tester 测试得到以下结果:

【讨论】:

这很有趣,知道为什么会这样,为什么^.*(?![.]tmp$) 不会吗? 你早期的.* 已经匹配了整个字符串,所以剩下的排除不再起作用了。 就我的目的而言,这行得通,而其他答案却没有。谢谢! 回复有点晚了,我知道,但对于其他人来说,像我一样想知道@ŁukaszZaroda 问题..这可能是因为行尾字符(“\n”和“\ r")【参考方案4】:
.*[^a]$

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

【讨论】:

我已经扩展了我的问题,因为原始示例似乎与我的情况不完全匹配。你能解决吗?【参考方案5】:

试试这个

/.*[^a]$/

[] 表示字符类,^ 反转字符类以匹配除a 之外的所有内容。

【讨论】:

【参考方案6】:

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

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

.*[^a]$

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

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

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

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

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

或更通用的版本:

.,n-1$|.*[^firstchar][^secondchar]$ 其中 n 是您要禁止的字符串的长度(对于abc,它是 3),而 firstcharsecondchar、... 是字符串的第一个、第二个...第 n 个字符(对于 abc 它会是a,然后是b,然后是c)。

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

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

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

【讨论】:

.,2$|.*[^a][^b][^c]$ 不匹配 ccc【参考方案7】:

这个问题很老,但我找不到更好的解决方案,我在这里发布了我的问题。 查找所有 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

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

如果您使用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

【讨论】:

以上是关于字符串的正则表达式不以给定的后缀结尾的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式匹配不以某些字符开头或结尾的单词?

正则表达式匹配空间不以 char 开头/结尾

正则表达式 - 以特定字符串开头但不以另一个子字符串结尾

不以元音开头或结尾的单词的正则表达式?

js正则表达式过滤以指定字符开头以指定字符结尾的文本内容

C ++ 11正则表达式匹配一个不以句点结尾的完整单词?