Home > Back-end >  JS string invert match (RegEx)
JS string invert match (RegEx)

Time:03-17

I have a string and I want to divide the parts that match a regex from rest of the text.

var str = 'Lorem ipsum [asdasd]dolor si[@@]c amet';
var brackets = str.match(/\[[\s\S] \]);  // ['[asdasd]', '[@@]']
var lipsum = ???                         // ['Lorem ipsum ', 'dolor si', 'c amet']

Is there any way to do this natively?

CodePudding user response:

[\s\S] will match everything, because \s matches any whitespace character and \S matches any non-whitespace character. You can thus use . instead.

let text = 'Lorem ipsum [asdasd]dolor si[@@]c amet';

let brackets = text.match(/\[. ?\]/g);
console.log(brackets)

As pointed out by @The fourth bird, using a negated character class is way faster ! You should thus use /\[[^\][]*]/g instead.


In order to match the other part, splitting the string is not a reliable solution: if the [...] are at start or end of the string, it will create empty strings.

Here is one way to do so using match() instead:

let text = 'Lorem ipsum [asdasd]dolor si[@@]c amet';

let lipsum = text.match(/(?<=\]|^)[^[\]] (?=\[|$)/g);
console.log(lipsum)

The regex used is the following:

(?<=\]|^)[^[\]] (?=\[|$)
  • (?<=): Positive lookbehind.
    • \]: Matches ].
    • |: Or.
    • ^: Start of the string.
  • [^[\]] : Matches any character other than [ and ], between one and unlimited times, as much as possible.
  • (?=): Positive lookahead.
    • \[: Matches [.
    • |: Or.
    • $: End of the string.

Instead of matching the parts enclosed in [...], we match the parts enclosed in ]...[. Using lookarounds allows square brackets to not be included.

CodePudding user response:

Instead of using match, you can use split with a pattern matching from [...] in a capture group and get all the matches in one array.

var str = 'Lorem ipsum [asdasd]dolor si[@@]c amet';
console.log(str.split(/(\[[^\][]*])/));

If you want separate matches for the bracket and lipsum, you might use the same pattern with for example reduce:

const str = '[Lorem ipsum [asdasd]dolor si[@@]c amet';
const res = str
    .split(/(\[[^\][]*])/)
    .reduce((a, c) => {
    /^\[[^\][]*]$/.test(c) ? a.brackets.push(c) : a.lipsum.push(c); return a;
}, {brackets:[], lipsum:[]})

console.log(res);

  • Related