RegEx: lookahead get only first occurrence

Viewed 220

(modified) Trying to get only first match of condition (?<=Location:.*?\().*?(?=\))

Here is data:

--batchresponse_bla_bla_bla_\r\n--changesetresponse__bla_bla_bla_\r\nLocation: https://site.ru/CRM/api/data/v9.0/gm_preorders(a341eb4e-2fdf-eb11-a30b-ac1f6b465e3b)\r\nOData-EntityId: https://site.ru/CRM/api/data/v9.0/gm_preorders(a341eb4e-2fdf-eb11-a30b-ac1f6b465e3b)\r\n_bla_bla_bla_\r\n--changesetresponse__bla_bla_bla_Location: https://site.ru/CRM/api/data/v9.0/gm_preorders(a841eb4e-2fdf-eb11-a30b-ac1f6b465e3b)\r\nOData-EntityId: https://site.ru/CRM/api/data/v9.0/gm_preorders(a841eb4e-2fdf-eb11-a30b-ac1f6b465e3b)\r\n_bla_bla_bla_\r\n--changesetresponse_n_bla_bla_bla_\r\nLocation: https://site.ru/CRM/api/data/v9.0/gm_preorders(74748d08-2ee6-eb11-a30b-ac1f6b465e3b)\r\nOData-EntityId: https://site.ru/CRM/api/data/v9.0/gm_preorders(74748d08-2ee6-eb11-a30b-ac1f6b465e3b)\r\nn_bla_bla_bla_\r\n--changesetresponse_etc

and it returns:

match 1:    a341eb4e-2fdf-eb11-a30b-ac1f6b465e3b
match 2:    a341eb4e-2fdf-eb11-a30b-ac1f6b465e3b
match 3:    a841eb4e-2fdf-eb11-a30b-ac1f6b465e3b
match 4:    a841eb4e-2fdf-eb11-a30b-ac1f6b465e3b
match 5:    74748d08-2ee6-eb11-a30b-ac1f6b465e3b
match 6:    74748d08-2ee6-eb11-a30b-ac1f6b465e3b

Is there a possibility to match only first occurrence of each match (so i need 3 matches: 1, 3 and 5) with lookbehind and lookahead and without grouping or other conditions?

Found solution with a help:

(?<=Location:[^(]*?\().*?(?=\))
2 Answers

You may use

(?<=Location:[^(]*\([^(]*\()[^)]*(?=\))
(?<=Location:[\w\W]*?\()(.*?)(?=\))(?![\w\W]*\1)

See the regex demo #1 and regex #2 demo.

Details:

  • (?<=Location:[^(]*\([^(]*\() - a location preceded with Location:, zero or more chars other than (, a (, and then again zero or more chars other than ( and then a (
  • [^)]* - zero or more chars other than )
  • (?=\)) - a ) char must appear immediately on the right.
  • (?<=Location:[\w\W]*?\() - a positive lookbehind that matches a location that is immediately preceded with
    • Location: - a Location: string
    • [\w\W]*? - zero or more chars as few as possible
    • \( - a ( char
  • (.*?) - Group 1: zero or more chars other than line break chars, as few as possible
  • (?=\)) - immediately to the right, there must be a ) char.
  • (?![\w\W]*\1) - no Group 1 value cannot be located further in the string.

You may use this dynamic length lookbehind assertion in a regex without using MULTILINE mode:

(?<=^(?:(?!\bLocation:)[^])*?\bLocation:[^(]*\()[^)]+

RegEx Details:

  • (?<=: Start lookbehind condition
    • ^: Start position
    • (?:(?!\bLocation:)[\s\S])*?: Match 0 or more of any character including newline as long as it is not followed by Location: word
    • \bLocation:: Match word Location:
    • [^(]*\(: Followed by 0 or more non-( characters and a (
  • ): End lookbehind condition
  • [^)]+: Match 1+ of any character that is not a )
Related