-1

I am trying to split a string into an array of text contents which each are present within the [@ and ] delimiters. Just characters in between [@and ] are allowed to match. Being provided with a string like ...

const stringA = '[@Mary James], [@Jennifer John] and [@Johnny Lever[@Patricia Robert] are present in the meeting and [@Jerry[@Jeffery Roger] is absent.'

... the following result is expected ...

[
  'Mary James',
  'Jennifer John',
  'Patricia Robert',
  'Jeffery Roger'
]

Any logic which leads to the expected outcome can be used.

A self search for a solution brought up the following applied regex ...

stringA.match(/(?<=\[@)[^\]]*(?=\])/g);

But the result doesn't fulfill the requirements because the array features the following items ...

[
  'Mary James',
  'Jennifer John',
  'Johnny Lever[@Patricia Robert',
  'Jerry[@Jeffery Roger'
]
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Sonali
  • 3
  • 2
  • Why doesn't it fulfill your requirement? What is it getting wrong? – Justin Morgan - On strike Feb 18 '22 at 16:24
  • 1
    [`/\[@(?[^\[\]]+)\]/g`](https://regex101.com/r/v234aT/1) ... `[ ...'[@Mary James], [@Jennifer John] and [@Johnny Lever[@Patricia Robert] are present in the meeting and [@Jerry[@Jeffery Roger] is absent.'.matchAll(/\[@(?[^\[\]]+)\]/g) ].map(({ groups: { content } }) => content);` – Peter Seliger Feb 18 '22 at 16:25
  • @JustinMorgan ... the OP's regex does not feature the opening bracket within the character class, thus changing the OP's `/(?<=\[@)[^\]]*(?=\])/g` to `(?<=\[@)[^\[\]]*(?=\])` already solves the OP's problem for most environments not including safari browsers due to the lookbehind which is not supported. – Peter Seliger Feb 18 '22 at 16:31

2 Answers2

0

Close, just missing the exclusion of [:

stringA.match(/(?<=\[@)[^\[\]]*(?=\])/g);
//                       ^^ exclude '[' as well as ']'
kelsny
  • 23,009
  • 3
  • 19
  • 48
0

The OP's regex does not feature the opening bracket within the negated character class, thus changing the OP's /(?<=\[@)[^\]]*(?=\])/g to (?<=\[@)[^\[\]]*(?=\]) already solves the OP's problem for most environments not including safari browsers due to the lookbehind which is not supported.

Solution based on a regex ... /\[@(?<content>[^\[\]]+)\]/g ... with a named capture group ...

const sampleText = '[@Mary James], [@Jennifer John] and [@Johnny Lever[@Patricia Robert] are present in the meeting and [@Jerry[@Jeffery Roger] is absent.'

// see ... [https://regex101.com/r/v234aT/1]
const regXCapture = /\[@(?<content>[^\[\]]+)\]/g;

console.log(
  Array.from(
    sampleText.matchAll(regXCapture)
  ).map(
    ({ groups: { content } }) => content
  )
);
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37