Regex- How to capture everything up until another named capture group

I have the following text:

J.smith (2022-05-02 01:22:02) Hi There,

How are you doing today

Just wanted to check in

Bobby123 (2022-05-02 07:39:00):Hello ,

Im doing good thank you for asking

Thanks!

I want to have three named capture groups of Name, Time, and Text:

Bobby123

2022-05-02 01:22:02

Hello ,

Im doing good thank you for asking

Thanks!

My main issue is trying to create a named capture group for text. Every regex I’ve tried captures everything for the text, but the text group should stop after it reaches the second named capture group (name) of Bobby123.

Here’s what I have so far:

(?<by>([\S]+)) \((?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\)\: 

https://regex101.com/r/VCIUH9/1

>Solution :

You can use

(?<by>\S+) \((?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\):\s*(?<text>.*(?:\n(?!\S+ \(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\):).*)*)

See the regex demo.

Details:

  • (?<by>\S+) – Group "by": one or more non-whitespaces
  • \( – a space and (
  • (?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) – a datetime pattern
  • \): – a ) and :
  • \s* – zero or more whitespaces
  • (?<text>.*(?:\n(?!\S+ \(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\):).*)*) – Group "text":
    • .* – the rest of the line
    • (?:\n(?!\S+ \(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\):).*)* – zero or more lines that do not start with any word, one space, a datetime pattern and then ): string.

Leave a Reply