【问题标题】:Regular expression to apply backspace characters正则表达式应用退格字符
【发布时间】:2013-05-17 08:19:41
【问题描述】:

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

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

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

结果为“Hello World12”。当然,我也想把“12”去掉,但是明显不符合我的表达方式。

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

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    这基本上是How can we match a^n b^n with Java regex? 的变体,所以我们可以在那里重用它的答案:

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

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

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

    (这意味着:

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

    )

    【讨论】:

    • 在正则表达式中,\b 不是表示断字吗?如果你真的想匹配\b,你需要转义:\\b
    • @BuhBuh:\b 在字符类中,这意味着\u0008。见msdn.microsoft.com/en-us/library/4edbef7e.aspx
    • 酷,我不知道。谢谢。
    【解决方案2】:

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

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

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

    【讨论】:

    • @WouterHuysentruit:我遍历输入字符串并操作堆栈。
    • +1 我明白了,谢谢。虽然我更喜欢这种方法以提高可读性,但我必须选择 KennyTM 的答案,因为我明确要求使用正则表达式。
    • SO:从哪里得到你想要的东西和十几个 cmets 为什么这是一个坏主意!
    • 嗯,我们当前的代码看起来很像你的提议。但我想知道如何用一个正则表达式来做到这一点,我自己也搞不清楚。这就是我提出问题的原因。
    • 伪代码中存在一个错误:如果堆栈为空,则您正在将退格字符压在上面。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2023-04-03
    • 1970-01-01
    • 2017-05-10
    相关资源
    最近更新 更多