【问题标题】:Regex for string not ending with given suffix不以给定后缀结尾的字符串的正则表达式
【发布时间】:2019-02-21 04:34:24
【问题描述】:

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

这匹配

b
ab
1

这不匹配

a
ba

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

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

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

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

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

【问题讨论】:

    标签: regex


    【解决方案1】:

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

    .*(?<!a)$
    

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

    看看here on Regexr

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

    .*(?<!ab)$
    

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

    【讨论】:

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

    使用不是(^) 符号:

    .*[^a]$
    

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

    For multiple characters,把他们都放在自己的字符集中就行了:

    .*[^a][^b]$
    

    【讨论】:

    • +1,需要注意的是这与空字符串不匹配(可能是也可能不是预期的),所以意思是“任何不在括号中的字符”。
    • @0A0D:包含空格的字符串不是空字符串。
    • @0A0D 实际上,这无须争论,这是事实
    • @Doorknob:与aecb 不匹配。
    • 不,这也不允许“acb”。
    【解决方案3】:

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

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

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

    【讨论】:

    • 这很有趣,知道为什么这行得通以及为什么 ^.*(?![.]tmp$) 行不通吗?
    • 您早期的 .* 确实已经匹配了整个字符串,因此剩余的排除项不再起作用。
    • 出于我的目的,这行得通,而其他答案则行不通。谢谢!
    • 我知道回复有点晚了,但对于其他人来说,就像我一样,关于@ŁukaszZaroda 问题..这可能是因为行尾字符(“ “ 和 ” ")
    【解决方案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
          8$fb
          q(c
          '
          jd8a
          8$fb
          q(c
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^a]$"
          8$fb
          q(c
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^b]$"
          jd8a
          q(c
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^c]$"
          jd8a
          8$fb
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^a][^b]$"
          jd8a
          q(c
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^a][^c]$"
          jd8a
          8$fb
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^a^b]$"
          q(c
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^a^c]$"
          8$fb
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^b^c]$"
          jd8a
          balter@spectre3:~$ printf 'jd8a
          8$fb
          q(c
          ' | grep ".*[^b^c^a]$"
          

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

          不好:https://regex101.com/r/MJGAmX/2
          好的:https://regex101.com/r/LzrIBu/2

          【讨论】:

            猜你喜欢
            • 2022-01-09
            • 2019-04-10
            • 2010-09-30
            相关资源
            最近更新 更多