alvini
alvini

Reputation: 23

ReGex, How to find second instance of string

If I want to get the Name between “for” and “;” which is NISHER HOSE, can you help me find the correct regex expression as there is more than one "for’ and “;” in the string

Data Owner Approval Needed for Access Request #: 2137352 for NISHER HOSE; CONTRACTOR; Manager: MUILLER, TIM (TWM0069)

Using the regular expression (?<=for).*(?=;) I get the wrong match Access Request #: 2137352 for NISHER HOSE; CONTRACTOR - see screenshot on https://www.regextester.com/

Thanks

Upvotes: 2

Views: 631

Answers (3)

Ryszard Czech
Ryszard Czech

Reputation: 18641

Use

(?<=\bfor )(?![^;]*\bfor\b)[^;]+

See proof.

Explanation

--------------------------------------------------------------------------------
  (?<=                     look behind to see if there is:
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    for                      'for '
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    [^;]*                    any character except: ';' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    for                      'for'
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  [^;]+                    any character except: ';' (1 or more times
                           (matching the most amount possible))

Upvotes: 1

adelriosantiago
adelriosantiago

Reputation: 8134

The main issue here is that there are two "for". If you want to catch the name then use the ":" as a delimiter to catch the second "for":

enter image description here

The name will be captured in group 1. If you decide to use a lookahead/lookbehind just bear in mind that these may or may not be supported depending on the regex engine.

Upvotes: 0

The fourth bird
The fourth bird

Reputation: 163577

If you only want to assert for on the left, you should and make sure to not match for again and you should exclude matching a ; while asserting there is one at the right.

(?<=\bfor )(?:(?!\bfor\b)[^;])+(?=;)

Explanation

  • (?<=\bfor ) Assert for at the left
  • (?:(?!\bfor\b)[^;])! Match 1+ times any char except ; if from the current position not directly followed by for surrounded by word boundaries
  • (?=;) Assert ; directly at the right

Regex demo

Upvotes: 1

Related Questions