0

Given a string, I would like to replace all abs by a, and all single as by 1, such that

X_ab_X-a%X

becomes

X_a_X-1%X

Replacing all as or all abs alone is pretty easy (here in JS)

mystring.replace(/a/gm, '1');
// mystring.replace(/ab/gm, 'a');

but I'm not seeing how to combine the two. All possible substrings can occur in mystring such that first replacing ab by TMP_UNIQUE_STRING won't work.

(Perhaps regexes aren't the right tool for the job.)

Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
  • Replace them alone but start with `ab` and use `TMP_UNIQUE_STRING`. Three replacements in total. – axiac Apr 04 '16 at 14:23
  • Replace `ab` with some random string that never occurs in the wild, replace `a` with `1`, then replace your random string with `a`? Silly, but it uses non-regex string replacement and avoids turning `ab` all the way into `1`. – Adam V Apr 04 '16 at 14:23
  • Thanks for your comments! Unfortunately, there is is no "string that never occurs in the wild". I'll try to make that even clearer in the question. – Nico Schlömer Apr 04 '16 at 14:26
  • Possible duplicate of [Replace ,(comma) by .(dot) and .(dot) by ,(comma)](http://stackoverflow.com/questions/34238005/replace-comma-by-dot-and-dot-by-comma) – Tushar Apr 04 '16 at 14:34

3 Answers3

4

You can use String#replace with the callback.

var str = "X_ab_X-a%X".replace(/ab?/g, function($0) {
    return $0 === 'a' ? '1' : 'a';
});

Using ES6 Arrow functions,

"X_ab_X-a%X".replace(/ab?/g, $0 => $0 === 'a' ? '1' : 'a')
Tushar
  • 85,780
  • 21
  • 159
  • 179
2

You can use a simple regex with alternation, and inside a replace callback, check the value and replace accordingly:

var re = /ab|a/g; 
var str = 'X_ab_X-a%X';
var result = str.replace(re, function(val) {
  return val === "ab" ? "a" : "1";
});
document.body.innerHTML = result;

Note that ab should come first in the alternation as the first branch matched "wins".

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I suggest alternation because I surmise that `a` and `ab` are just placeholders and there can be other values. Surely, a final pattern can be optimized (as in Tushar's answer). – Wiktor Stribiżew Apr 04 '16 at 14:29
0

how about

("X_ab_X-a%X").replace(/a(?!b)/gm, '1');

Lookahead Zero-Length Assertions are the best.

Dominique Fortin
  • 2,212
  • 15
  • 20