【问题标题】:How to remove extra spaces from a specific string?如何从特定字符串中删除多余的空格?
【发布时间】:2015-11-22 11:28:14
【问题描述】:

我有一个类似下面的字符串:

Ireland, UK, United States of America,     Belgium, Germany   , Some     Country, ...

我需要 RegexString.Replace 函数的帮助来删除多余的空格,这样结果会像:

Ireland,UK,United States of America,Belgium,Germany,Same Country,

谢谢。

【问题讨论】:

  • 天哪,这很容易……没想到。谢谢
  • 只需用逗号、修剪和String.Join 分隔即可。
  • 嗯,不确定,因为您的 Some Country 有很多空格,而预期的输出 Same Country 只有一个空格。真的吗?我猜String.Join(",", "Ireland, UK, United States of America, Belgium, Germany , Some Country,".Split(","c).Select(Function(m) m.Trim()).ToArray()) 不会工作。

标签: regex vb.net string replace tags


【解决方案1】:

您可以通过用逗号分隔输入,然后将多个空格修剪并缩小为 1,然后String.Joining 来实现这一点。

仅展示如何使用 LINQ 来完成:

Console.Write(String.Join(",", _
    "Ireland, UK, United States of America,     Belgium, Germany   , Some     Country," _
     .Split(","c) _
     .Select(Function(m) Regex.Replace(m.Trim(), "\p{Zs}{2,}", " ")) _
     .ToArray()))

关键是Regex.Replace(m.Trim(), "\p{Zs}{2,}", " "),其中多个空格缩小为1。

结果:Ireland,UK,United States of America,Belgium,Germany,Some Country,

【讨论】:

    【解决方案2】:

    虽然 stribizhev 写的答案很适合这种情况,但我想利用这个机会强调使用正则表达式处理简单任务对性能的(负面)影响。

    比正则表达式更快(x2)的替代方法(在处理这些情况时总是很慢)

    我的方法是基于递归删除空格。我创建了两个版本:第一个带有传统循环 (withoutRegex) 和第二个依赖 LINQ (withoutRegex2;实际上,除了Regex 部分之外,它与 stribizhev 的答案相同。

    Private Function withoutRegex(input As String) As String
    
        Dim output As String = ""
    
        Dim temp() = input.Split(","c)
        For i As Integer = 0 To temp.Length - 1
            output = output & recursiveSpaceRemoval(temp(i).Trim()) & If(i < temp.Length - 1, ",", "")
        Next
    
        Return output
    
    End Function
    
    Private Function withoutRegex2(input As String) As String
    
        Return String.Join(",", _
        input _
        .Split(","c) _
        .Select(Function(x) recursiveSpaceRemoval(x.Trim())) _
        .ToArray())
    
    End Function
    
    Private Function recursiveSpaceRemoval(input As String) As String
    
        Dim output As String = input.Replace("  ", " ")
    
        If output = input Then Return output
        Return recursiveSpaceRemoval(output)
    
    End Function
    

    为了证明我的观点,我创建了以下测试框架:

    Dim input As String = "Ireland, UK, United States of America,     Belgium, Germany   , Some     Country"
    Dim output As String = ""
    
    Dim count As Integer = 0
    Dim countMax As Integer = 20
    Dim with0 As Long = 0
    Dim without As Long = 0
    Dim without2 As Long = 0
    
    While count < countMax
    
        count = count + 1
        Dim sw As Stopwatch = New Stopwatch
        sw.Start()
        output = withRegex(input)
        sw.Stop()
        with0 = with0 + sw.ElapsedTicks
    
        sw = New Stopwatch
        sw.Start()
        output = withoutRegex(input)
        sw.Stop()
        without = without + sw.ElapsedTicks
    
        sw = New Stopwatch
        sw.Start()
        output = withoutRegex2(input)
        sw.Stop()
        without2 = without2 + sw.ElapsedTicks
    
    End While
    
    MessageBox.Show("With: " & with0.ToString)
    MessageBox.Show("Without: " & without.ToString)
    MessageBox.Show("Without 2: " & without2.ToString)
    

    其中withRegex指的是stribizhev的回答,即:

    Private Function withRegex(input As String) As String
    
        Return String.Join(",", _
        input _
        .Split(","c) _
        .Select(Function(m) Regex.Replace(m.Trim(), "\p{Zs}{2,}", " ")) _
        .ToArray())
    
    End Function
    

    这是一个简单的测试框架,可以分析非常快速的动作,其中每一位都很重要(20 次循环迭代的重点正是试图提高测量的可靠性)。也就是说:即使更改调用方法的顺序,结果也会受到影响。

    无论如何,在我的所有测试中,方法之间的差异或多或少都保持一致。我经过一些测试得到的平均值是:

    With: 2500-2700
    Without: 1100-1300
    Without2: 900-1200
    

    注意:至于这是对正则表达式性能的一般批评(至少,在足够简单的情况下,可以很容易地用我在这里展示的替代方案替换),关于如何改进它的任何建议( .NET 中正则表达式的性能)将非常受欢迎。但请避免笼统的不清楚的陈述,并尽可能具体(例如,通过建议对提议的测试框架进行更改)。

    【讨论】:

    • 使用声明为静态只读的已编译正则表达式,性能没有问题。
    • @stribizhev 我该怎么做?公共静态(共享)变量只读?我想测试最佳的正则表达式条件并确认/驳回我的假设。请帮帮我!
    • @stribizhev 你有一个现成的测试框架。尽可能多地修改它并向我(OP 和未来的读者)展示如何提高正则表达式的性能。我写这篇文章是因为我认为它是相关的,如果你证明它不相关,我会删除它(也会学习如何正确使用正则表达式,甚至可能在不久的将来改变我在这方面的方法)。
    • 令人惊讶的行为!无论如何......重点很清楚(正则表达式在这种情况下显然更慢+更快的递归替代方案)并且只要没有太多人似乎完全意识到这个事实,我会暂时在这里回答这个问题存在。
    • 您如此投入测试性能而忽略了我们的解决方案不同的事实:我的删除了所有 Unicode 空格(例如硬空间&amp;#0160;),而您的只删除了常规的 32 码空间。好吧,我同意仅删除 32 个空格的任何非正则表达式解决方案都会更快。尽管如此,当我们不知道输入字符串中有哪些空格等待我们时,使用正则表达式是救命稻草。
    猜你喜欢
    • 2011-08-05
    • 2013-06-03
    • 1970-01-01
    • 2022-07-24
    • 2022-10-07
    • 2013-07-20
    相关资源
    最近更新 更多