11

I have a function f similar to

function f(str){
    alert("abc"+str);
}

Now, I want to use JavaScript special charecter "\b" in such a way that I can choose if I want to display the hardcoded string "abc" or not. For example,

f("\b\b"+"yz"); //should output "ayz"

I tried the same, but it does not work. In other words, I want to concat a string with a backspace character so that I can remove last characters from the string.

Can we do this in JavaScript?

EDIT The real code is too much big (its a HUGE 1 liner that concats many many strings). To map that in above example, we cannot edit the function f, so do whatever you want from outside function f.

hrishikeshp19
  • 8,838
  • 26
  • 78
  • 141

5 Answers5

10

The problem comes from the fact that \b is just another character in the ASCII code. The special behaviour is only when implemented by some string reader, for example, a text terminal.

You will need to implement the backspace behaviour yourself.

function RemoveBackspaces(str)
{
    while (str.indexOf("\b") != -1)
    {
        str = str.replace(/.?\x08/, ""); // 0x08 is the ASCII code for \b
    }
    return str;
}

Example: http://jsfiddle.net/kendfrey/sELDv/

Use it like this:

var str = RemoveBackspaces(f("\b\byz")); // returns "ayz"
Kendall Frey
  • 43,130
  • 20
  • 110
  • 148
  • 1
    Not a bad idea, but I'm finding this doesn't execute right. For Example, `RemoveBackspaces("abcde\b\b"+"yz");` returns 'yz' – Wesley Aug 09 '12 at 21:05
  • 4
    pretty cool fiddle, can you explain that regular expression a bit? I am too high to grasp that. – hrishikeshp19 Aug 09 '12 at 21:08
  • 2
    The regex matches any character (`.`) followed by a backspace (`\x08`), and replaces all those occurrences with an empty string. – Kendall Frey Aug 09 '12 at 21:08
  • pretty cool..thanks. I will accept this if I dont get an answer that does my problem from outside function f. – hrishikeshp19 Aug 09 '12 at 21:12
  • @hrishikeshp19 This does work outside the function. Just call it on the string that the function returns. – Kendall Frey Aug 09 '12 at 21:13
  • @KendallFrey: Nono...f returns nothing in real problem. See my edit. Actually, I have a huge line that concats many many strings. My string "str" is one of them, and I just want my string to eat up previous string. – hrishikeshp19 Aug 09 '12 at 21:16
  • @hrishikeshp19 Then concat the entire string together, including `\b`'s, and call the function on the result, on the next line. – Kendall Frey Aug 09 '12 at 21:18
  • I am prototying it. String.prototype.RemoveBackspaces =function(){} References: Kendall Frey. – hrishikeshp19 Aug 09 '12 at 21:22
  • I edited my code to take `\b`'s at the start of the string into account. – Kendall Frey Aug 09 '12 at 21:28
  • You can express `\b` as a backspace if you put it in a character class like `[\b]`. See [this question](http://stackoverflow.com/q/17438100/5743988) – 4castle Jul 15 '16 at 13:44
1

EDIT: I realized this may not be what the OP was looking for, but it is definitely the easier way to remove characters from the end of a string in most cases.

You should probably just use string.substring or string.substr, both of which return some portion of string. You can get the substring from 0 to the string's length minus 2, then concatenate that with "yz" or whatever.

DGH
  • 11,189
  • 2
  • 23
  • 24
1

Interesting question. I first checked some assumptions about \b in JS.

If you try this:

console.log('abc\b\byz');

You get the same answer of 'abcyz'.

This means, it is not a function of concatentation, but a fundamental error in the approach.

I would modify your approach to use SubString, then to take the index of \b and slice out the previous character.

Wesley
  • 5,381
  • 9
  • 42
  • 65
1

Something like this:

function f(str, abc){
   if(!abc) abc = "abc";
   if (str.indexOf("\b") != "undefined")
   {
       abc = abc.slice(0,-1);
       str = str.replace("\b","");
       f(str, abc);
   }
   else alert(abc+str);
}

and as an added bonus you get to use recursion!

note that this is a little slower than doing it this way:

function f(str){
    var count = 0;
    var abc = "abc";
    for(var i = 0; i < str.length; i++)
    { 
       if(str[i] = "\b") //at least i think its treated as one character...
       count++;
    }
    abc = abc.slice(0, count * -1);
    alert(abc+str);
}
Phillip Schmidt
  • 8,805
  • 3
  • 43
  • 67
0

I'm processing the backspace \b, but it always has the ANSI erase in line \x1B[K after the \bs. So what I do is this:

function applyBackspaces(str) {
  // Catch character + \b or character + \b\x1B[K and delete it
  const re = /.?[\u0008](\u001b\[K)?/
  while (re.test(str)) {    
    str = str.replace(re, "");
  }
  return str;
}

// wrote "up", backspace+erase, backspace+erase (used backspace key)
// wrote "ls", backspace+backspace+erase (used clear line command C-u)
// wrote uptime
applyBackspaces('up\b\x1B[K\b\x1B[Kls\b\b\x1B[Kuptime') // uptime
Artur Carvalho
  • 6,901
  • 10
  • 76
  • 105