I have a string constructed from user keyboard types, so it might contain '\b'
characters (backspaces).
I want to clean the string, so that it will not contain the '\b'
characters, as well as the characters they are meant to erase. For instance, the string:
String str = "\bHellow\b world!!!\b\b\b.";
Should be printed as:
Hello world.
I have tried a few things with replaceAll, and what I have now is:
System.out.println(str.replaceAll("^\b+|.\b+", ""));
Which prints:
Hello world!!.
Single '\b'
is handled fine, but multiples of it are ignored.
So, can I solve it with Java's regex?
EDIT:
I have seen this answer, but it seem to not apply for java's replaceAll.
Maybe I'm missing something with the verbatim string...
Java regex - erase characters followed by \b (backspace)
[\b] matches a backspace character apparently.
Backslashes in Java. The backslash \ is an escape character in Java Strings. That means backslash has a predefined meaning in Java. You have to use double backslash \\ to define a single backslash. If you want to define \w , then you must be using \\w in your regex.
A dedicated symbol for "backspace" exists as U+232B ⌫ but its use as a keyboard label is not universal. The backspace is distinct from the delete key, which in paper media for computers would punch out all the holes to strike out a character, and in modern computers deletes text following it.
It can't be done in one pass unless there is a practical limit on the number of consecutive backspaces (which there isn't), and there is a guarantee (which there isn't) that there are no "extra" backspaces for which there is no preceding character to delete.
This does the job (it's only 2 small lines):
while (str.contains("\b"))
str = str.replaceAll("^\b+|[^\b]\b", "");
This handles the edge case of input like "x\b\by"
which has an extra backspace at the start, which should be trimmed once the first one consumes the x
, leaving just "y"
.
Stack<Character> stack = new Stack<Character>();
// for-each character in the string
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
// push if it's not a backspace
if (c != '\b') {
stack.push(c);
// else pop if possible
} else if (!stack.empty()) {
stack.pop();
}
}
// convert stack to string
StringBuilder builder = new StringBuilder(stack.size());
for (Character c : stack) {
builder.append(c);
}
// print it
System.out.println(builder.toString());
Regex, while nice, isn't well suited to every task. This approach is not as concise as Bohemian's, but it is more efficient. Using a stack is O(n) in every case, while a regex approach like Bohemian's is O(n2) in the worst case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With