43

I'm banging my head against a wall with a regular expression. I'm trying to define an expression that excludes exactly this text 'System' (case insensitive), but can contain the word 'System' providing it's not just that.

Examples:

  • System == INVALID
  • SYSTEM == INVALID
  • system == INVALID
  • syStEm == INVALID
  • asd SysTem == Valid
  • asd System asd == Valid
  • System asd == Valid
  • asd System == Valid
  • asd == Valid
Kieron
  • 26,748
  • 16
  • 78
  • 122

4 Answers4

91

Try this:

^(?!system$)

Or this to match the whole line:

^(?!system$).*$

The regex has a negative look-ahead on its beginning, which doesn't match if "system" is the entire string.

Kobi
  • 135,331
  • 41
  • 252
  • 292
  • 1
    Just out of curiosity, how does the ?! operator work? I've never used that one (though I've used pretty much regex I tend to find solutions which don't use 'not'). – Alxandr Jun 03 '10 at 09:30
  • 1
    @Alxandr - it checks what follows your current position. For example, `c(?!4)` will match c from `Doc12`, but not the c on `Doc42`. A look-around doesn't capture, so I don't have to worry about replacing the digit, or check edge case (for example, if c were the last character: `Doc`). – Kobi Jun 03 '10 at 09:36
  • If you don't care about matching the whole line (if you only care about it matching the pattern or not), adding `.*$` doesn't make sense, right? – x-yuri Sep 05 '17 at 16:26
  • @x-yuri - Right, that's the first option. I you're just filtering string, for example, `.*$` is not needed. – Kobi Sep 05 '17 at 18:57
  • I'm trying this in a sql engine and it gives "invalid perl operator" - is there a PCRE equivalent? – dcsan Jul 09 '21 at 20:52
  • @dcsan - This should work with [PCRE](https://www.pcre.org/current/doc/html/pcre2syntax.html#SEC19). On SQL these are usually easier, because you can combine multiple regex patterns using `AND`, `OR`, and `NOT`. The example here doesn't require a regex, it can be `WHERE x != 'system'` – Kobi Jul 10 '21 at 07:45
5

Reject if it matches ^system$ (make sure i flag is ON).

Amarghosh
  • 58,710
  • 11
  • 92
  • 121
  • 2
    This should be the first option, or course. I naturally (and possibly wrongly) assumed the OP cannot do it. – Kobi Jun 03 '10 at 09:32
  • 1
    I can't use this because I'm using a system that uses rules and the rule has to match a regex, I don't have the option to say apply the rule if the regex doesn't match. – Ruan Mendes Jan 25 '22 at 19:45
1
^$|^.{1-5}$|.{7}|^[^s]|^.[^y]|^..[^s]|^...[^t]|[^e].$|[^m]$ 

But use amarghosh's answer if you can.

(updated as per suggestion below)

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • heh, I wrote that without testing it. I'm kind of shocked that it actually worked first try. The first two clauses are redundant though, so: (^.{1-6}$)|(.{8})|(^[^s])|(^.[^y])|(^..[^s])|(^...[^t])|([^e].$)|([^m]$) Nice tip about ?! though - I hadn't heard of it. – Steve Bennett Jun 03 '10 at 09:46
  • oops. that regex lets through "systuem". (and fails on empty string, which is apparently acceptable?) try: ^$|^.{1-5}$|.{7}|^[^s]|^.[^y]|^..[^s]|^...[^t]|[^e].$|[^m]$ – Steve Bennett Jun 03 '10 at 09:51
  • Steve - Welcome to stack overflow. It is best to update your answer than to add another one as a comment. Also, start the regex line with 4 spaces - it will format it as code. – Kobi Jun 03 '10 at 09:56
-1

To match all the words of COMMON_LOGGER except for COMMON_LOGGER. (i.e., not followed by a dot), you can use the negative lookahead assertion (?!.) to exclude any matches that are immediately followed by a dot. Here's an example regex: c6290d3a-e1c4-41f5-b45b-6afdb1cfe3b2

COMMON_LOGGER(?!\.)