Match everything except for specified strings

前端 未结 7 1670
名媛妹妹
名媛妹妹 2020-11-22 14:25

I know that the following regex will match \"red\", \"green\", or \"blue\".

red|green|blue

Is there a straightforward way of making it mat

相关标签:
7条回答
  • 2020-11-22 14:29

    Matching any text but those matching a pattern is usually achieved with splitting the string with the regex pattern.

    Examples:

    • c# - Regex.Split(text, @"red|green|blue") or, to get rid of empty values, Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x)) (see demo)
    • vb.net - Regex.Split(text, "red|green|blue") or, to remove empty items, Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s)) (see demo, or this demo where LINQ is supported)
    • javascript - text.split(/red|green|blue/) (no need to use g modifier here!) (to get rid of empty values, use text.split(/red|green|blue/).filter(Boolean)), see demo
    • java - text.split("red|green|blue"), or - to keep all trailing empty items - use text.split("red|green|blue", -1), or to remove all empty items use more code to remove them (see demo)
    • groovy - Similar to Java, text.split(/red|green|blue/), to get all trailing items use text.split(/red|green|blue/, -1) and to remove all empty items use text.split(/red|green|blue/).findAll {it != ""}) (see demo)
    • kotlin - text.split(Regex("red|green|blue")) or, to remove blank items, use text.split(Regex("red|green|blue")).filter{ !it.isBlank() }, see demo
    • scala - text.split("red|green|blue"), or to keep all trailing empty items, use text.split("red|green|blue", -1) and to remove all empty items, use text.split("red|green|blue").filter(_.nonEmpty) (see demo)
    • ruby - text.split(/red|green|blue/), to get rid of empty values use .split(/red|green|blue/).reject(&:empty?) (and to get both leading and trailing empty items, use -1 as the second argument, .split(/red|green|blue/, -1)) (see demo)
    • perl - my @result1 = split /red|green|blue/, $text;, or with all trailing empty items, my @result2 = split /red|green|blue/, $text, -1;, or without any empty items, my @result3 = grep { /\S/ } split /red|green|blue/, $text; (see demo)
    • php - preg_split('~red|green|blue~', $text) or preg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY) to output no empty items (see demo)
    • python - re.split(r'red|green|blue', text) or, to remove empty items, list(filter(None, re.split(r'red|green|blue', text))) (see demo)
    • go - Use regexp.MustCompile("red|green|blue").Split(text, -1), and if you need to remove empty items, use this code. See Go demo.

    NOTE: If you patterns contain capturing groups, regex split functions/methods may behave differently, also depending on additional options. Please refer to the appropriate split method documentation then.

    0 讨论(0)
  • 2020-11-22 14:33

    I had the same question, the solutions proposed were almost working but they had some issue. In the end the regex I used is:

    ^(?!red|green|blue).*
    

    I tested it in Javascript and .NET.

    .* should't be placed inside the negative lookahead like this: ^(?!.*red|green|blue) or it would make the first element behave different from the rest (i.e. "anotherred" wouldn't be matched while "anothergreen" would)

    0 讨论(0)
  • 2020-11-22 14:34

    Matching Anything but Given Strings

    If you want to match the entire string where you want to match everything but certain strings you can do it like this:

    ^(?!(red|green|blue)$).*$

    This says, start the match from the beginning of the string where it cannot start and end with red, green, or blue and match anything else to the end of the string.

    You can try it here: https://regex101.com/r/rMbYHz/2

    Note that this only works with regex engines that support a negative lookahead.

    0 讨论(0)
  • 2020-11-22 14:34

    All except word "red"

    var href = '(text-1) (red) (text-3) (text-4) (text-5)';
    
    var test = href.replace(/\((\b(?!red\b)[\s\S]*?)\)/g, testF); 
    
    function testF(match, p1, p2, offset, str_full) {
      p1 = "-"+p1+"-";
      return p1;
    }
    
    console.log(test);

    All except word "red"

    var href = '(text-1) (frede) (text-3) (text-4) (text-5)';
    
    var test = href.replace(/\(([\s\S]*?)\)/g, testF); 
    
    function testF(match, p1, p2, offset, str_full) {
      p1 = p1.replace(/red/g, '');
      p1 = "-"+p1+"-";
      return p1;
    }
    
    console.log(test);

    0 讨论(0)
  • 2020-11-22 14:53

    If you want to make sure that the string is neither red, green nor blue, caskey's answer is it. What is often wanted, however, is to make sure that the line does not contain red, green or blue anywhere in it. For that, anchor the regular expression with ^ and include .* in the negative lookahead:

    ^(?!.*(red|green|blue))
    

    Also, suppose that you want lines containing the word "engine" but without any of those colors:

    ^(?!.*(red|green|blue)).*engine
    

    You might think you can factor the .* to the head of the regular expression:

    ^.*(?!red|green|blue)engine     # Does not work
    

    but you cannot. You have to have both instances of .* for it to work.

    0 讨论(0)
  • 2020-11-22 14:56

    Depends on the language, but there are generally negative-assertions you can put in like so:

    (?!red|green|blue)
    

    (Thanks for the syntax fix, the above is valid Java and Perl, YMMV)

    0 讨论(0)
提交回复
热议问题