Recombine capture groups in one regex?

I am trying to handle input groups similar to:

'...A.B.'

and want to withdraw '.....AB'

.

Another example:

'.C..Z..B.' ==> '......CZB'

I worked with the following:

'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1")

      

returns:

"....."

      

and

'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$2")

      

returns:

"AB"

      

but

'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1$2")

      

returns

"...A.B."

      

Is there a way to return

"....AB"

      

with one regex?

I was only able to accomplish this with

'...A.B.'.replace(/(\.*)([A-Z]*)/g, "$1") + '...A.B.'.replace(/(\.*)([A-Z]*)/g, "$2")

      

==> ".....AB"

+3


source to share


1 answer


If the goal is to move everything .

to the beginning and everything A-Z

to the end, then I believe the answer to

with one regex?

- "not".

Separately, I don't think there is an easier or more efficient way than two calls replace

- but not the ones you showed. Instead of this:

var str = "...A..B...C.";
var result = str.replace(/[A-Z]/g, "") + str.replace(/\./g, "");
console.log(result);
      

Run codeHide result




(I don't know what you want to do with the symbols .

, not A-Z

, so I ignored them.)

If you really want to do it with a single call replace

(for example, one pass along the line makes a difference), you can, but I'm sure you will have to use the callback function and state variables:

var str = "...A..B...C.";
var dots = "";
var nondots = "";
var result = str.replace(/\.|[A-Z]|$/g, function(m) {
  if (!m) {
    // Matched the end of input; return the
    // strings we've been building up
    return dots + nondots;
  }
  // Matched a dot or letter, add to relevant
  // string and return nothing
  if (m === ".") {
    dots += m;
  } else {
    nondots += m;
  }
  return "";
});
console.log(result);
      

Run codeHide result


This is of course incredibly ugly. :-)

+1


source







All Articles