Reputation: 2800
I'm trying to create a JS regex that matches !next
either at the beginning or end of the line.
Currently I'm using /(^!next|!next$)/i
which works. However that's obviously kind of ugly to read and not DRY, so I'm looking to improve.
The closest I've come is this:
/(?=!next)[^$]/i
But that actually just matches everything (and it occurs to me now that I misremembered the way that ^
works inside character classes, so this solution is garbage anyway).
I've searched the web and SO, and I'm totally stumped.
Upvotes: 1
Views: 123
Reputation:
You could try
function beginningOrEnd(input, search) {
const pos = input.search(search);
return pos === 0 || pos === input.length - search.length;
}
beginningOrEnd("hey, !help", "!help");
This uses search.length
, so obviously search
must be a string.
Or, you could construct the regexp yourself:
function beginningOrEnd(search) {
return new RegExp(`^${search}|${search}\$`, "i");
}
beginningOrEnd("!help").test(input)
In the real world, you'd want to escape special regexp characters appropriately, of course.
Upvotes: 3
Reputation: 4854
Here's a fun one, using regex conditionals:
/(^)?!next(?(1)|$)/gm
How it works is it captures the beginning-of-line anchor, and, if it is not present, matches the end-of-line anchor instead.
Personally, though, I'd still argue in favour of your solution over mine because it's more readable to someone who doesn't have an extremely thorough knowledge of regexes (and is more portable).
For added fun, here's another version (that's even uglier than your initial variant):
/!next(?:(?<=^.{5})|(?=$))/gm
I'd still recommend sticking with the classic alternation, though.
And, finally, one that works in JS (no, really):
/(?:^|(?=.{5}$))!next/gm
Upvotes: 4