5

我有一个来自 telnet 客户端的字符串。该字符串包含我需要应用的退格字符。每个退格键应删除一个先前键入的字符。

我正在尝试使用正则表达式在一次替换中执行此操作:

string txt = "Hello7\b World123\b\b\b";
txt = Regex.Replace(txt, ".\\\b", "", RegexOptions.ECMAScript);

结果是“Hello World12”。当然,我也想去掉“12”,但显然和我的表达不符。

在某种程度上,它应该重复替换,直到没有更多的匹配。关于如何使用单个正则表达式实现这一点的任何想法?

4

2 回答 2

4

我不会尝试为此使用正则表达式,因为它非常难以阅读,而且我觉得如果没有任何类似 perl 的正则表达式魔法扩展,使用普通的正则表达式甚至是不可能的。我的建议是这样的(类似于 python 的伪代码):

stack = []
for char in str:
    if char == BACKSPACE and not stack.isEmpty():
        stack.pop()
    else:
        stack.push(char)

result = ''.join(stack)

立即清楚发生了什么以及它是如何工作的。

于 2013-05-17T08:30:58.037 回答
4

这基本上是我们如何将 a^nb^n 与 Java 正则表达式匹配的变体?,所以我们可以在那里重用它的答案:

var regex = new Regex(@"(?:[^\b](?=[^\b]*((?>\1?)[\b])))+\1");
Console.WriteLine(regex.Replace("Hello7\b World123\b\b\b", ""));

此外,.NET 正则表达式引擎支持平衡组,因此我们可以使用不同的模式:

var regex = new Regex(@"(?<L>[^\b])+(?<R-L>[\b])+(?(L)(?!))");

(这表示:

  1. 匹配一个或多个非退格,将它们命名为“L”,
  2. 然后跟着一个或多个退格键,将它们命名为“R”,条件是每个“R”必须有一个对应的“L”,
  3. 如果还剩下任何“L”,则放弃匹配(因为(?!)不匹配)。

)

于 2013-05-17T08:31:56.577 回答