Search code examples
javascriptregextypescriptregex-lookaroundsregex-group

group string after keywords (at, after, until) ignore order


I want to group any text after one of these keyword for

input: /send 1 at 11:00pm for 3min

desired result: postNumber = 1, sendAt = 11:00pm, duration = 3min

input: /send 1 for 3min

desired result: postNumber = 1, duration = 3min

input: /send 1 at 11:00pm

desired result: postNumber = 1, sendAt = 11:00pm

input: /send 1 until 11:00pm

desired result: postNumber = 1, until = 11:00pm

input: /send 1 for 3min at 11:00 pm

desired result: postNumber = 1, sendAt = 11:00 pm, duration = 3min

input: /send 1 at 11am for 1 h

desired result: postNumber = 1, sendAt = 11am, duration = 1 h

I've made the following regex but could'nt figure out how to make it agnostic to order of the keywords input

(?<postNumber>\d+)(?: at (?<sendAt>.*))?(?: for (?<duration>.*))?(?: until (?<until>.*))?

I tried to add positive lockahead but it matched all the digits in the first group (?<postNumber>\d+)(?=(?: at (?<timeToSend>.*)))?(?=(?: for (?<duration>.*)))?(?=(?: until (?<until>.*)))?


Solution

  • You can enclose each of the capture groups in a positive lookahead pattern so that they can be matched in any order:

    \/send\s+(?<postNumber>\d+)(?=(?:.*\bat\s+(?<sendAt>\d+(?::\d+)?\s*\S+))?)(?=(?:.*\bfor\s+(?<duration>\d+\s*\S+))?)(?=(?:.*\buntil\s+(?<until>\d+(?::\d+)?\s*\S+))?)
    

    Demo: https://regex101.com/r/Ks5YHN/2