I need to remove the last block of text between parentheses in a string, but only when there are two blocks of text between parentheses at the end of that string.
For instance, if the string is
Text (aaa) Text (bbb) Text (ccc) (ddd).
I need to get
Text (aaa) Text (bbb) Text (ccc).
While, if the string is
Text (aaa) Text (bbb) Text (ccc).
I need to preserve it as it is.
I've tried several regular expressions using https://regexr.com (e.g. /\s\(([^)] )\)\s\(([^)] )\)/
), but none of them is right for me (I'm not very experienced with regex).
Would you give me any suggestions?
CodePudding user response:
You can use
text = text.replace(/(\([^()]*\))\s*\([^()]*\)(?![\s\S]*\([^()]*\))/, '$1')
// Or, if there is always a dot and end of string (with possible trailing whitespace)
text = text.replace(/(\([^()]*\))\s*\([^()]*\)(?=\.\s*$)/, '$1')
See the regex demo. Details:
(\([^()]*\))
- Group 1 ($1
):(
, zero or more chars other than(
and)
and then a)
char\s*
- zero or more whitespaces\([^()]*\)
-(
, zero or more chars other than(
and)
and then a)
char(?![\s\S]*\([^()]*\))
- a negative lookahead that ensures there is no other(...)
substring anywhere to the right of the current location.(?=\.\s*$)
- a positive lookahead that requires.
, then zero or more whitespaces and then an end of string immediately to the right of the current location.
See the JavaScript demo:
const texts = ['Text (aaa) Text (bbb) Text (ccc) (ddd).','Text (aaa) Text (bbb) Text (ccc).'];
const rx = /(\([^()]*\))\s*\([^()]*\)(?![\s\S]*\([^()]*\))/;
for (const text of texts) {
console.log(text, '=>', text.replace(rx, '$1'));
}