0

I'm trying to split this string into kind of a structure,

20:33:15     From Deekshitha Oku : Me too

into

{ time: "20:33:15", name: "Deekshitha Oku", message: "Me too" }

So for that, I wrote a Regex,

(([0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])(.*?)(From)\s(.*?).:\s(.*?).+

But it's not what I expecting, it wired here. What I expect is something like this,

[
  "20:33:15",
  "Deekshitha Oku",
  "Me too"
]

const match = "20:33:15     From Deekshitha Oku : Me too".match(/(([0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])(.*?)(From)\s(.*?).:\s(.*?).+/);

console.log(match);

What is the issue with this regex, I was tried many different ways :(

1
  • 1
    You have too many capture groups in your regex. Each time you use a new set of parentheses, you create a new capture group, and thus a new result in your regex result. Instead, use non capturing groups starting with (?: except for when you actually want the content inside that capture group to be returned to you. Commented Mar 1, 2021 at 16:39

3 Answers 3

3

Try to change your regex to this:

^((?:[0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]).*?From\s(.*?).:\s(.*).+$

Then you can generate the object:

const match = "20:33:15     From Deekshitha Oku : Me too".match(/^((?:[0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]).*?From\s(.*?).:\s(.*).+$/);
const object = { time: match[1], name: match[2], message: match[3] };

console.log(object);


EDIT: Using named capture groups, you can just use match.name etc. and don't have to generate a new object:

const match = "20:33:15     From Deekshitha Oku : Me too".match(/^(?<time>(?:[0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]).*?From\s(?<name>.*?).:\s(?<message>.*)$/).groups;

console.log(match);

Note the added .groups after the match call.

Sign up to request clarification or add additional context in comments.

2 Comments

Anyhow above regex skips the last character, so I found this working ^(?<time>(?:[0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]).*?From\s(?<name>.*?).:\s*(?<message>.*$)$
Yeah, my fault, I fixed it in my answer.
1

Don't split, put your captures into named capture groups:

(?<time>^.{1,8}) *From (?<person>[^:]+?)(?= *:) *: *(?<message>.*$)

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

console.log(/(?<time>^.{1,8}) *From (?<person>[^:]+?)(?= *:) *: *(?<message>.*$)/.exec(`20:33:15     From Deekshitha Oku : Me too`).groups)

Comments

1

I think you just need some small tweaks:

/((?:[0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])\s*From\s*([^:]*):\s*(.*)/

First, don't use parens when you don't want to capture the information (like you had around From). Second, use (?:) instead of () if you just want the parens for grouping, not for capturing. Third, non-greedy matches are more complicated and error-prone than a construct like [^:]* (in my opinion). Saying "match all not-colon" is more explicit.

See https://regex101.com/r/3dLjbV/1 to play with my attempt at your problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.