1

Let's say I have this string: "a_b_c_d_restofthestring" and I only want to keep (e.g.) 2 underscores. So,

 "a_b_cdrestofthestring"
 "abc_d_restofthestring"

Are both valid outputs.

My current implementation is:

let str = "___sdaj___osad$%^&*";

document.getElementById('input').innerText = str;

let u = 0;
str = str.split("").reduce((output, c) => {
  if (c == "_") u++;
  return u < 2 || c != "_" ? output + c : output;
});

document.getElementById('output').innerText = str;
<div id="input"></div>
<div id="output"></div>

But I'd like to know if there's a better way...

6
  • You want to remove everything after the first two underscores? Commented Aug 2, 2018 at 17:39
  • str = str.replace(/^(.*?_.*?_)(.*)$/,(_,a,b) => a+b.replace(/_/g,'')) Commented Aug 2, 2018 at 17:40
  • do you want all six possible strings with two of four underscores as result? Commented Aug 2, 2018 at 17:42
  • I'd change str.split("") to [...str]. Commented Aug 2, 2018 at 18:00
  • No, @shreyasminocha, I want to remove all underscores except two of them, no matter which ones. All other characters remain. Commented Aug 3, 2018 at 6:59

2 Answers 2

2

Your code seems to work fine, but here's a one-liner regular expression that replaces all but the last two underscores from the input string.

let input = "___sdaj___osad$%^&*";
let output = input.replace(/_(?=(.*_){2})/g, '');

console.log("input: " + input);
console.log("output: " + output);

This of course is not very generalized, and you'd have to modify the regular expression every time you wanted to say, replace a character other than underscore, or allow 3 occurrences. But if you're okay with that, then this solution has a bit less code to maintain.


Update: Here's an alternate version, that's fully generic and should perform a bit better:

let input = "___sdaj___osad$%^&*";

function replace(input, char = '_', max = 2, replaceWith = '') {
  let result = "";
  const len = input.length;
  
  for (let i = 0, u = 0; i < len; i++) {
    let c = input[i];
    result += (c === char && ++u > max) ? replaceWith : c;
  }
  
  return result;
}

console.log("input: ", input);
console.log("output: ", replace(input));

See this jsPerf analysis.

Sign up to request clarification or add additional context in comments.

Comments

2

You could take a regular expression which looks for an underscore and a counter of the keeping underscores and replace all others.

var string = "a_b_c_d_restofthestring",
    result = string.replace(/_/g, (c => _ => c && c-- ? _ : '')(2));
    
console.log(result);

1 Comment

+1 Clever. Faster than my Regex solution (see updated jsPerf) probably because it doesn't require any backtracking, and it's easier to make generic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.