Reputation: 414
I have a string includes parentheses inside:
I want to uppercase this string (except this) and (this)
I want to transform it into:
I WANT TO UPPERCASE THIS STRING (except this) AND (this)
What is the best way to do it in JavaScript? If I have to use regex, please explain clearly because I am not good at regex.
Best regards,
Upvotes: 0
Views: 427
Reputation: 207537
Probably is a better way, but a quick and dirty way to use not
var x = 'I want to uppercase this string (except this) and (this)'.replace( /(^[^(]+)|(\)[^(]+)/g, function (a,b) { return (a || b).toUpperCase()})
console.log(x)
Upvotes: 1
Reputation: 175916
It may be simpler to uppercase the lot then lowercase between parens
var str = "I want to uppercase this string (except this) and (this)";
str = str.toUpperCase().replace(/(\(.+?)\)/g, m => m.toLowerCase());
To preserve case:
var str = "I want to uppercase this string (eXcEpT ThIs) and (ThIS)";
str = str.toUpperCase().replace(/\((.+?\))/g, (m, c, o) => str.substr(o, m.length));
> I WANT TO UPPERCASE THIS STRING (eXcEpT ThIs) AND (ThIS)
Upvotes: 2
Reputation: 318312
You can use a regex, and then replace with a callback
var str = "I want to uppercase this string (except this) and (this)";
var res = str.replace(/[^()](?=([^()]*\([^()]*\))*[^()]*$)/g, t => t.toUpperCase());
console.log(res)
The regular expression does the following
NODE EXPLANATION
-----------------------------------------
[^()] any character except: '(', ')'
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
( group and capture to \1 (0 or more times
(matching the most amount possible)):
--------------------------------------------------------------------------------
[^()]* any character except: '(', ')' (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
\( '('
--------------------------------------------------------------------------------
[^()]* any character except: '(', ')' (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
\) ')'
--------------------------------------------------------------------------------
)* end of \1 (NOTE: because you are using a
quantifier on this capture, only the
LAST repetition of the captured pattern
will be stored in \1)
--------------------------------------------------------------------------------
[^()]* any character except: '(', ')' (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
$ before an optional \n, and the end of
the string
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
/g global
Without any regular expressions
var str = "I want to uppercase this string (except this) and (this)";
var par = false;
var res = str.split('').map(function(c) {
par = c == '(' ? true : c == ')' ? false : par;
return par ? c : c.toUpperCase();
}).join('')
console.log(res)
Upvotes: 1
Reputation: 785761
This might be simpler:
var str = 'I want to uppercase this string (except this) and (this)';
var repl = str.replace(/[a-z]+(?![^()]*\))/g, m => m.toUpperCase())
console.log(repl);
//=> "I WANT TO UPPERCASE THIS STRING (except this) AND (this)"
This assumes (
and )
are balanced and unescaped in input.
Negative lookahead (?![^()]*\))
asserts we match a string that is not followed by a )
with no (
or )
in between.
Upvotes: 1