1

I'm looking for a regex expression to run through several strings and match these words in them:

Maces Armour Evasion Shields

Excluding strings which contain these words alongside:

Swords Axes Staves

For example (these 2 lines are one string):

12% Increased Physical Damage with Maces
8% Increased Armour

should be a match, but this one should not be (these 2 lines are also one string but it contains forbidden word "swords" with needed word "evasion"):

10% Increased Evasion
8% Increased Attack Speed with Swords

How do I exclude that list?

Unihedron
  • 10,902
  • 13
  • 62
  • 72
VixinG
  • 1,387
  • 1
  • 17
  • 31
  • why `10% Increased Evasion` is not a match? – Braj Aug 17 '14 at 12:49
  • @user3218114 These 2 lines are a full string – VixinG Aug 17 '14 at 12:50
  • This application is written in C#, it's not mine, but it accepts regex expressions. I aleady tried things like (maces|armour|evasion|shields) and it was displaying matched strings, but with swords and other stuff too, thats why I want to exclude these. – VixinG Aug 17 '14 at 12:52

2 Answers2

4

You can use a lookahead for needed words and a negative lookahead for forbidden words (if your regex engine allows these two features):

(?s)(?=.*\b(?:Maces|Armour|Evasion|Shields)\b)(?!.*\b(?:Swords|Axes|Staves)\b)^.+$
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • @Unihedron: You can't avoid the backtracking even if you put the anchor at the begining, it changes nothing. – Casimir et Hippolyte Aug 17 '14 at 12:55
  • @Unihedron: atomic groups are not needed here since the groups don't contain any quantifiers, or if you have this kind of words set: `abcd|abc|defgh|def`. However, your way works well too. – Casimir et Hippolyte Aug 17 '14 at 13:00
  • Okay, nevermind, I have no idea what regex this program accepts, but it looks like it's working somehow with your answer.. Thanks :P – VixinG Aug 17 '14 at 13:08
3

You can use a singleline regex:

/^(?=.*(?>Maces|Armour|Evasion|Shields))(?!.*(?>Swords|Axes|Staves)).+$/s
  • (?=.*(?>Maces|Armour|Evasion|Shields)) Asserts that one of these words are present in string [no backtracking]
  • (?!.*(?>Swords|Axes|Staves)) Asserts that none of these words are present in string [no backtracking]

Here is a regex demo!

Unihedron
  • 10,902
  • 13
  • 62
  • 72