Khanh Le
Khanh Le

Reputation: 414

Uppercase every characters outside the parentheses

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

Answers (4)

epascarello
epascarello

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

Alex K.
Alex K.

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

adeneo
adeneo

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

anubhava
anubhava

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

Related Questions