简体   繁体   中英

Hubot regexes - stop at the first match, rather than trying all of them?

I have a simple Hubot script that is looking for certain trigger words, then replying with a URL based on those trigger words.

A slightly contrived example:

robot.hear /CAT/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/cats"
robot.hear /YELLOWBIRD/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/yellowbirds"
robot.hear /BIRD/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/birds"

The problem is, one of the trigger words (BIRD) is a substring of another trigger word (YELLOWBIRD).

In this case, I want to only trigger on the more specific regex (YELLOWBIRD).

However, Hubot is currently triggering on both regexes - ie it will send in:

This is a URL - www.example.com/browse/yellowbirds
This is a URL - www.example.com/browse/birds

Is there a way to have Hubot treat the list of regexes like a case - as in, it will work through them from the top, and the first one it hits, it will break out, and not process the remaining ones? (Or maybe there's a way to make the "BIRD" regex ignore if if there's a yellow there).

And bonus question - is there perhaps a better or more idiomatic way of organising these regexes and replies? Some kind of lookup table or something?

Try this:

robot.hear /CAT/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/cats"
    msg.finish()
robot.hear /YELLOWBIRD/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/yellowbirds"
    msg.finish()
robot.hear /BIRD/i, (msg) ->
    msg.send "This is a URL - www.example.com/browse/birds"
    msg.finish()

You say that you're looking for words but your regexes are looking for strings . If you really do want to match words then you could toss some \\b s into your regexes:

\\b
Matches a zero-width word boundary, such as between a letter and a space.

so you could say:

robot.hear /\bCAT\b/i, (msg) -> ...
robot.hear /\bYELLOWBIRD\b/i, (msg) -> ...
robot.hear /\bBIRD\b/i, (msg) -> ...

so that your /\\bBIRD\\b/i will match 'big bird' but not 'angry yellowbird' or 'blackbird pie' .

If you still want to match 'blackbird' then you could just toss a simple conditional into the mix, something like this:

robot.hear /(\S*)bird/i, (msg) ->
  if((msg.match[1] || '').toLowerCase() !== 'yellow')
    # respond in here...

I don't have a Hubot setup that I can easily play with so that last one might not be quite right but hopefully it is close enough to illustrate the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM