Exclusive Or in Regular Expression

后端 未结 13 1705
小鲜肉
小鲜肉 2020-12-05 10:06

Looking for a bit of regex help. I\'d like to design an expression that matches a string with \"foo\" OR \"bar\", but not both \"foo\" AND \"b

相关标签:
13条回答
  • 2020-12-05 10:27

    I'd use something like this. It just checks for space around the words, but you could use the \b or \B to check for a border if you use \w. This would match " foo " or " bar ", so obviously you'd have to replace the whitespace as well, just in case. (Assuming you're replacing anything.)

    /\s((foo)|(bar))\s/
    
    0 讨论(0)
  • 2020-12-05 10:28

    If your regex language supports it, use negative lookaround:

    (?<!foo|bar)(foo|bar)(?!foo|bar)
    

    This will match "foo" or "bar" that is not immediately preceded or followed by "foo" or "bar", which I think is what you wanted.

    It's not clear from your question or examples if the string you're trying to match can contain other tokens: "foocuzbar". If so, this pattern won't work.

    Here are the results of your test cases ("true" means the pattern was found in the input):

    foo: true
    bar: true
    foofoo: false
    barfoo: false
    foobarfoo: false
    barbar: false
    barfoofoo: false
    
    0 讨论(0)
  • 2020-12-05 10:30

    I tried with Regex Coach against:

    x foo y
    x bar y
    x foobar y
    

    If I check the g option, indeed it matches all three words, because it searches again after each match.
    If you don't want this behavior, you can anchor the expression, for example matching only on word boundaries:

    \b(foo|bar)\b
    

    Giving more context on the problem (what the data looks like) might give better answers.

    0 讨论(0)
  • 2020-12-05 10:31

    This will take 'foo' and 'bar' but not 'foobar' and not 'blafoo' and not 'blabar':

    /^(foo|bar)$/
    
    ^ = mark start of string (or line)
    $ = mark end of string (or line)
    

    This will take 'foo' and 'bar' and 'foo bar' and 'bar-foo' but not 'foobar' and not 'blafoo' and not 'blabar':

    /\b(foo|bar)\b/
    
    \b = mark word boundry
    
    0 讨论(0)
  • 2020-12-05 10:31

    You might want to consider the ? conditional test.

    (?(?=regex)then|else)
    

    Regular Expression Conditionals

    0 讨论(0)
  • 2020-12-05 10:32
    \b(foo)\b|\b(bar)\b
    

    And use only the first capture group.

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