skip to Main Content

I have the following string:

testInputs.abc_def.alpha=abc^ORtestVars.var23.nameISEMPTY^testInputs.alpha_bravo.more.otheroneCONTAINSsomething^testVars.anotherone!=abc^testVars.mYVar!=abc

I need it to match

testInputs.abc_def.alpha
testVars.var23.name
testInputs.alpha_bravo.more.otherone
testVars.anotherone
testVars.mYVar

I can match all occurences, but the problem is that it also matches some operators that it shouldnt:

ISEMPTY
CONTAINS

(And a slew of others like IN, NOT IN, etc.)

I have an array that I can join to create an alternation, but the issue is maintaining the match, without the prohibted substrings. As it stands now instead of

testVars.var23.name

I end up with

testVars.var23.nameISEMPTY

Similarly, I match testInputs.alpha_bravo.more.otheroneCONTAINS

The rules as it stands are:

  • Match can start with testInputs. or testVars.
  • Any alpha numeric, regardless of case, as well as underscores(_) and periods(.)
  • The substring after the testInputs or testVars can be any length
  • There can be multiple matches in a string
  • The match can also be in the form of {{var}} e.g {{testInputs.myinput}}=abc or {{testVars.my_var}}ISEMPTY, but I have left the above clear of that so it’s easier to read.

So far I have tried the following:

(({{)?(?:testInputs.|testVars.)[a-zA-Z0-9_.]+(}})?)

And tried a few variations of the lookahead/behind

(?!CONTAINS|ISEMPTY)

But have been unsuccessful in excluding the Invalid substrings, while still matching the piece of the match I’m looking for.

2

Answers


  1. You can match each character with a negative lookhead pattern to exclude known keywords (feel free to add more):

    (?:testInputs|testVars).(?:[w.](?!ISEMPTY|CONTAINS|OR|IN|[^w.]))*w
    

    Demo: https://regex101.com/r/L14Te5/3

    Login or Signup to reply.
  2. You can match the following regular expression:

    test(?:Inputs|Vars).(?:(?=.*test(?:Inputs|Vars).)[^!=A-Z]+|(?!.*test(?:Inputs|Vars).)[^!=]+)
    

    provided these three rules apply:

    • The match begins 'testInputs.' or 'testVars.'.
    • Following the match of 'testInputs.' or 'testVars.', if one of those strings appears later in the string, as many characters as possible in the character class [^!=A-Z] are matched.
    • Following the match of 'testInputs.' or 'testVars.', if neither of those strings appears later in the string, as many characters as possible in the character class [^!=] are matched.

    Demo

    The expression can be broken down as follows.

    test(?:Inputs|Vars).          # match literal
    (?:                            # begin non-capture group
      (?=.*test(?:Inputs|Vars).)  # positive lookahead asserts literal appears
                                   # later in the string
      [^!=A-Z]+                    # match one or more chars in the char class
    |                              # or
      (?!.*test(?:Inputs|Vars).)  # negative lookahead asserts literal does not
                                   # appear later in the string
      [^!=]+                       # match one or more chars in the char class
    )                              # end non-capture group
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search