Match on word, unless this word precedes it

Okay, given the following output

that was close, wasn’t it! - match
issues close #32 - no match (the word ‘issues’ can’t proceed ‘close’)

How do you fix this regex?


You can test it at

Here is what I’ve tried:

/\b(?!issues )(close)\b/i

But it seems I really need a negative lookbehind, which doesn’t seem to exist in JavaScript RegEx :frowning: as the following works in PHP

/\b(?<!issues )(close)\b/i

I also need to do this from a single RegEx, I can’t add JavaScript logic to look at the result, and I can’t add more RegExs to compare (this is an unfortunate requirement of the system I’m using).

Anyone have better RegEx king-fu?

If I understand what you’re after, this seems to work

1 Like

Hmm… that still returns true for both outputs.

Checkout my weird solution :smiley:

OK, the coffee :coffee: is starting to kick in.

This works, but only without the greedy
(hmmm, the greedy was there on regex101 but not in your examples here)


That definitely works, but unfortunately, I can’t use !regex.test, I only pass a regex into the system and that regex must be able to return true when it matches successfully and false when it shouldn’t match the given context.

Very clever though!

I still can’t get that to return false for the second phrase :frowning:

My bad, without the greedy it only finds the first one

I guess I need another cup!

Ah, I get what you mean now. Yeah, that greedy was only put there so you could see it try and match across all entries at regex101. Each line entry will actually be sent independently from each other in a real case scenario.

I’ve been having fun trying “guesses” but without any luck

I have seen “not supported at all” and I’ve seen JavaScript work-arounds (i.e. custom functions), but nothing that is a regex expression only.

This is a bit closer, but far from perfect

/\b((?!issues).{6}|\b) (close)\b/i

scratch that, I’ve been toying with it too long and don’t even see what I’m looking at

I’m starting to think this may be an impossible task and a true negative lookbehind is the only way to successfully pull it off.

As all methods I’ve been trying for the past countless hours have failed.

What are you using? Seems there’s just gotta be a way somehow.

It is for a command for Hubot, which has a “hear” method that receives a RegEx and when that RegEx matches a statement by a user, it then executes a command. I simply want it to not execute a command when the proceeding word is “issues” immediately followed with the word “close”.

It isn’t a big deal, as everything is functioning, it simply is a tad annoying that when I issue a command for it to close a github issue using hubot issues close #45, it is executing the github request and another request simultaneously.

Would approaching it from a different direction help, where “close #” won’t be responded to instead?

The problem is, the existing close response is literally /\bclose\b/i and is meant for fun more than “work”, and the new command works fine by using /new issues close #[0-9]+/i, the word close just forces both to be executed.

I’m not familiar with coffeescript, but if this is @jeffreylees coffee maybe he knows the syntax to have it compile into a function with an if in it?

Unfortunately, it is the way the Hubot API works that an IF can’t be applied. I think we just have to chalk this off to “this is how it must work” or we can try to add other words that surround the word “close” for the latter script so it matches on more specific phrases (like issues close does)

What flavor of regex do you need to use, please?

This works in my text editor, but I don’t know how to write it in JS.
From what I read (a year ago), JavaScript(Chrome) doesn’t support the negative lookbehind. Other flavors may.


JavaScript, but with a work-around for the lack of negative lookbehind support.

AFAICT Hubot compiles CoffeeScript into JavaScript and doesn’t support conditionals inside of functions

OK, thanks, Mittineague.

Yeah, that’s the problem. JavaScript doesn’t seem to support negative lookbehinds :frowning:

@Mittineague, if it helps any, here is the script

As you can see, it isn’t overly complicated, but there is simply a regex expression that must return true for the times you want it to respond. Once the regex parses, I can make it do anything. I guess, I could run a second regex inside the more global capture… actually this may work.

module.exports = (robot) ->
  robot.hear /\bclose\b/i, (msg) ->
    # run another regex here to test for 'issues close', if false, run msg.send
    msg.send msg.random images

I was just hoping to do it all in one regex and not have to add funky logic, but it seems with the lack of negative lookbehinds, I may have to add funky logic