【问题标题】:How to add a space before and after special characters如何在特殊字符前后添加空格
【发布时间】:2020-06-23 01:02:03
【问题描述】:

我试图在字符串中的特殊字符之前和之后添加一个空格,但前提是该特殊字符位于数字之间。 例如:

1/2 应该变成 1 / 2
1/2/3 应该变成 1 / 2 / 3
4,6 应该变成 4 , 6
8a,b 将保持 8a,b
8,9a 将变为 8 , 9a
1,6,a,c 会变成 1 , 6,a,c
等等等等。


我知道您可以使用以下代码将特殊字符替换为其他字符,但我不确定如何替换相同的特殊字符和前后的空格。

Regex.Replace(your_String, @"[^0-9a-zA-Z]+", "Something Else");

实现此目的最有效的方法是什么?

【问题讨论】:

  • 视情况而定。如果您认为特殊字符是已知列表,还是只是 ,/ 这两个字符?
  • @Franck 嘿,所以在我的情况下,基本上非字母和非数字将被视为特殊字符。
  • 期待大量文本或不是您最简单的解决方案仍然在缓冲区(对于非常大的字符串)或直接在整个数组(对于较小的字符串)上循环,并且只读取每个字符的字符并检查它们是否字节值落在 0-9 a-Z 的范围内,这只是 1 if 语句并通过添加或不添加空格来复制 StringBuilder 中的内容。
  • @Franck Ah - 希望避免这种情况:(。

标签: c# .net


【解决方案1】:

所以基本上非字母和非数字会被认为是特殊的 我的例子中的字符

您可以使用StringBuilder,以及Char.IsLetterOrDigit()Char.IsDigit(),如下所示:

static void Main(string[] args)
{
    string input = "1/2 1/2/3 4,6 8a,b 8,9a 8,9a 1,6,a,c";
    Console.WriteLine("input = " + input);

    StringBuilder sb = new StringBuilder(input);
    int i = 1;
    while(i < (sb.Length-1))
    {
        // "so basically non-letters and non-numbers would be considered special characters"
        if (!Char.IsLetterOrDigit(sb[i]))
        {
            // is there a digit to the left and right?
            if (Char.IsDigit(sb[i-1]) && Char.IsDigit(sb[i+1]))
            {
                sb.Insert(i, ' ');
                sb.Insert(i+2, ' ');
                i = i + 3;
            }
            else
            {
                i++;
            }
        }
        else
        {
            i++;
        }                
    }

    input = sb.ToString();
    Console.WriteLine("input = " + input);

    Console.Write("Press Enter to quit...");
    Console.ReadLine();
}

【讨论】:

    【解决方案2】:

    所以通常我会使用一个循环来记录前一个字符是什么,并且只循环一次以获得最快的代码,同时最容易维护它。

    // some test data
    var data = "adw/412f,9 356#%7";
    
    // much faster string building class
    var sb = new StringBuilder();
    
    // flag for spacing on non special char
    var previousIsSpecial = false;
    
    // linq to check each char only once
    data.ToList().ForEach(c =>
    {
        // get the byte once
        var b = (byte)c;
    
        // if it's a non special character. Decided to exclude [space], 0-9, a-z, A-Z
        if (b == 32 || (b >= 48 && b <= 57) || (b >= 65 && b <= 90) || (b >= 97 && b <= 122))
        {
            // add a space if the previous char was special and add the current character
            sb.Append((previousIsSpecial ? " " : "") + c);
    
            // mark this character as "not" special for the next loop
            previousIsSpecial = false;
        }
        else
        {
            // always add the space before a special character
            sb.Append(" " + c);
    
            // mark this character as special for the next iteration
            previousIsSpecial = true;
        }
    });
    
    // get the result
    var result = sb.ToString();
    

    【讨论】:

      【解决方案3】:

      看起来您想使用正则表达式,所以这里有一种方法可以使用正则表达式在由数字包围的特殊字符前后添加空格。其他循环方法很可能会像您所要求的那样更“高效”,但我猜您的意思可能与打字效率一样高效,而不是性能效率

      using System;
      using System.Text.RegularExpressions;
      using System.Collections.Generic;
      
      public class Program
      {
          public static void Main()
          {
              var testValues = new List<string>{@"1/2/3", @"4,6", @"8a,b", @"8,9a", @"1,6,a,c", @"1 2", @"1,,2", @"1234"};
              var digitSpecialDigitPattern = @"(\d)([^0-9a-zA-Z\s])(\d)";
              foreach (var input in testValues)
              {
                  Console.WriteLine($"input: {input}");
                  var output = input;
                  while (Regex.IsMatch(output, digitSpecialDigitPattern))
                  {
                      output = Regex.Replace(output, digitSpecialDigitPattern, @"$1 $2 $3");
                  }
                  Console.WriteLine($"output: {output}");
              }
          }
      }
      

      您可以在https://dotnetfiddle.net/pEc6Ok 处运行此程序并对其进行更改

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-13
        • 1970-01-01
        • 2017-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多