【问题标题】:Regex : I need to extract all words except the string `ignore`正则表达式:我需要提取除字符串 `ignore` 之外的所有单词
【发布时间】:2021-09-09 06:19:09
【问题描述】:

以此为例

hello-world
ignore-good-morning-ignore
good-night-ignore

我尝试过负面展望和负面展望

^(?<!ignore)\S+(?!ignore)$

不过好像是挑了三个字

预期结果

hello-world
good-morning
good-night

实际结果

hello-world
ignore-good-morning-ignore
good-night-ignore

【问题讨论】:

    标签: regex regex-lookarounds


    【解决方案1】:

    我建议交换逻辑并实际匹配您要忽略的单词并替换那些值,从而将字符串留在预期的输出中。例如:

    (?<=\S)-ignore\b|\bignore-(?=\S)
    

    查看在线demo。当我们将匹配的子字符串替换为空时,您可以在屏幕底部看到结果。


    • (?&lt;=\S) - 断言位置的后向回溯前面有一个非空白字符。
    • -ignore\b - 匹配 '-ignore' 后跟单词边界。
    • | - 或者:
    • \bignore- - 匹配一个单词边界,后跟 'ignore-'。
    • (?=\S) - 断言位置的正向预测后跟一个非空白字符。

    注意,如果您的字符串也可以只是“忽略”而没有其他任何内容,您也可以添加到交替中来捕获它。

    【讨论】:

    • 这是正确答案,应该被接受。
    【解决方案2】:

    如果您想捕获不同数量的多次出现,请尝试此版本,不带字符串的开头^ 和结尾$ 的标记(以便我们可以捕获所有内容):

    (?!\bignore\b)\b(\w+)\b
    

    地点:

    • (?!\bignore\b) - 否定前瞻断言我们将捕获的字符串不完全是单词“ignore”。
    • \b - 确保我们要捕获的单词是整个单词,而不是部分单词,例如“忽略”
    • (\w+) - 捕捉文字
    • \b - 如上所述,确保我们能捕捉到整个单词

    【讨论】:

    • 如果你不介意我挑一个小问题,这也会跳过像ignorethis 这样的词。也许前瞻中的单词边界可以解决它。
    • 很棒的发现!!是的,我没有考虑到这一点。我更新了前瞻,以确保这个词是严格的“忽略”。非常感谢@JvdV :)
    【解决方案3】:

    如果您使用 C#,您可以拆分字符串并跳过 ignore 条目:

    var words = new[]
    {
      "hello-world",
      "ignore-good-morning-ignore",
      "good-night-ignore",
      "good-ignore-night",
    };
    foreach (var word in words)
    {
      var word2 = string.Join("-", word.Split("-").Where(w => w != "ignore"));
      Console.WriteLine(word2);
    }
    /*
        Output:
          hello-world
          good-morning
          good-night
          good-night
    */
    
    

    【讨论】:

      【解决方案4】:

      使用正则表达式,只有一种方法可以匹配除 a 之外的所有内容
      某个字符串。

      当然,分割单词或短语来创建一个片段列表是完成这项任务的可靠方法,
      将特定句段与文本字符串匹配可能会有好处。

      事情是你会得到一个匹配的位置,而不必做很多字符串长度
      如果你要使用 split 之类的算法。

      对于正则表达式,唯一的方法是使用可以“跳过”单词或短语的引擎。 唯一可以做到这一点的引擎是 Perl、PCRE 或 Python“正则表达式”

      事实上,他们发明了一种结构,可以在匹配后跳过单词或短语。
      这是 (*SKIP) 构造。

      初步检查包含跳过,因为这是一个使用示例
      PCRE,我只是重用了一些代码作为函数调用 "(?1)" 来检查
      遍历流时前面没有单词。

      如果你不能使用 Perl / PCRE 风格的引擎,你最好使用
      你最喜欢的分割函数。

      ((?:-|\b)ignore(?:-|\b))(*SKIP)(?!)|(?:(?!(?1)).)+
      

      https://regex101.com/r/Wy21OZ/1

         (                             # (1 start)
            (?: - | \b )
            ignore
            (?: - | \b )
         )                             # (1 end)
         (*SKIP)(?!)
       | 
         (?: 
           (?! (?1) ) .
         )+
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 1970-01-01
        • 2017-07-07
        • 2019-11-12
        • 2014-04-01
        • 2011-01-05
        相关资源
        最近更新 更多