0

How to rewrite the regex ^(?!master).+@ without the negative lookahead?

Natalie Perret
  • 8,013
  • 12
  • 66
  • 129

2 Answers2

3
^(?:[^m]|m[^a]|ma[^s]|mas[^t]|mast[^e]|maste[^r]).*@

Update - in case you need one for both master and main:

^(?:[^m]|m[^a]|ma[^si]|mai[^n]|mas[^t]|mast[^e]|maste[^r]).*@
ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • not supposed to have a `+` instead of `*` at the end: `^(?:[^m]|m[^a]|ma[^s]|mas[^t]|mast[^e]|maste[^r]).+@`? – Natalie Perret Apr 15 '19 at 13:24
  • 2
    @EhouarnPerret the `+` means "one or more characters", while `*` means "zero or more characters". Given that we already matched at least one character in the brackets (for example `[^m]` is exactly one character), we may or may not need another one. Hence why it's `*` and not `+`. – ndnenkov Apr 15 '19 at 13:27
  • makes sense, you're awesome! – Natalie Perret Apr 15 '19 at 13:34
  • Happy to help <3 – ndnenkov Apr 15 '19 at 13:56
  • Work very well ! Even if that s*cks to be forced to use a such syntax... – TBG Oct 14 '22 at 07:36
  • However it doesn't work if you want to avoid `master` AND `main` :/ – TBG Dec 21 '22 at 13:43
  • 1
    @TBG then you can do a big `|` and repeat do the same for `main`. – ndnenkov Dec 21 '22 at 16:07
  • @ndnenkov I tried but it didn't work, at least when I tested it on regex101 ... Do you have a working example ? – TBG Dec 21 '22 at 17:23
  • @TBG well what didn't work exactly? Could you post a regex so that I could suggest a fix for it. – ndnenkov Dec 21 '22 at 19:17
  • @ndnenkov I started from your answer https://regex101.com/r/GYX742/1 and I modified it to also avoid main, here is one of my tries : https://regex101.com/r/dW7CzD/1 – TBG Dec 22 '22 at 11:22
  • 1
    @TBG here's an [updated working version](https://regex101.com/r/j03d9p/1). – ndnenkov Dec 22 '22 at 11:58
  • @ndnenkov Awesome, thanks a lot ! However I supposed there is no way of avoiding `mastere` or `mainu` being excluded ? And how would you generate that for a list of words ? I had a bash script but in fact it only works for one word, as I built it on your first answer... I think I will end up doing a loop on a "simple" regex, instead of finding a regex that covers all cases/words – TBG Dec 22 '22 at 15:26
  • 1
    @TBG the original question required stuff starting with `master` to be excluded, not `master` alone. So `mastere` and `mainu` change the scope of the question. Ask a separate one. And yes, if you have control over it (like it's a bash script) I wouldn't build a mega-regex and match against a list of words. Instead I would check one by one without regexes. xd – ndnenkov Dec 22 '22 at 16:14
2

You may phrase this problem as being logically equivalent to saying match any string which does not begin with master, and which contains an at symbol:

input = "some random text @";

if (input !~ /^master/ && input =~ /.*@.*/)   # or /.*@$/ if it must end in an @
    puts "MATCH"
end
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360