Java擦除后面跟有\b(退格)的字符



我有一个由用户键盘类型构建的字符串,因此它可能包含'b'字符(退格)。

我想清理字符串,这样它就不会包含'b'字符以及它们要擦除的字符。例如,字符串:

String str = "bHellowb world!!!bbb.";

应打印为:

Hello world.

我已经用replaceAll尝试了一些东西,现在我拥有的是:

System.out.println(str.replaceAll("^b+|.b+", ""));

打印:

你好,世界!!。

单个'b'处理良好,但忽略其倍数。

那么,我可以用Java的正则表达式来解决它吗?

编辑:

我已经看到了这个答案,但它似乎不适用于java的replaceAll
也许我遗漏了逐字逐句的字符串。。。

除非对连续退格的数量有实际限制(没有),并且有保证(没有)不存在没有前一个字符可删除的"额外"退格,否则不能一次完成。

这就完成了任务(只有两条细线):

while (str.contains("b"))
str = str.replaceAll("^b+|[^b]b", "");

这处理了像"xbby"这样的输入的边缘情况,它在开始时有一个额外的退格,一旦第一个消耗了x,就应该对其进行修剪,只留下"y"

这看起来像是Stack的作业

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虽然不错,但并不是很适合每项任务。这种方法不像波西米亚人的方法那样简洁,但它更有效。在任何情况下,使用堆栈都是O(n),而像Bohemian这样的正则表达式方法在最坏的情况下是O(n2)。

您试图解决的问题无法用单个正则表达式解决。问题是生成语言{any_symbol}*{any_symbol}^n{b}^n(这是您输入的特殊情况)的语法是不规则的。您需要将状态存储在某个位置(它在bb之前读取了多少符号),但DFA无法做到这一点(因为DFA不知道它能找到多少顺序符号)。所有提出的解决方案都只是适用于您的案例("bHellowb world!!!bbb.")的正则表达式,可以通过更复杂的测试轻松破解。

对于您的情况,最简单的解决方案是更换循环对中的

UPD:由@Bohemian提出的解决方案似乎完全正确:

UPD2:似乎java的正则表达式不仅可以解析常规语言,还可以解析具有递归前瞻性的{a}^n{b}^n等输入,因此在java的情况下,可以用单个正则表达式匹配这些组。感谢@Pshemo的评论和@Elist的编辑!

如果我正确理解了这个问题,这就是你的问题的解决方案:

String str = "bHellowb world!!!bbb.";
System.out.println(str.replace(".?\b", ""));

这是一个很好的谜题。我认为您可以使用正则表达式来删除相同数量的相同重复字符和bs(即,对于您的特定输入字符串):

String str = "bHellowb world!!!bbb.";
System.out.println(str.replaceAll("^b+|(?:([^b])(?=\1*+(\2?+b)))+\2", ""));

这是对How can we match a ^n b ^n with Java regex?的改编?。

请参阅IDEONE演示,我在其中添加了.replace("b","<B>"));,以查看是否还有b

输出:

Hello world.

仅限正则表达式的通用解决方案不在正则表达式范围内。。。目前

最新更新