【问题标题】:is there a splitByCharacterType method in c# like there is in Java?c# 中是否有一个 splitByCharacterType 方法,就像在 Java 中一样?
【发布时间】:2017-05-11 20:37:49
【问题描述】:

在Java 中有一个方法splitByCharacterType 接受一个字符串,例如0015j8*(,并将其拆分为"0015","j","8","*","("。 c#中有这样的内置函数吗?如果不是,我将如何构建一个函数来做到这一点?

【问题讨论】:

  • 这使用了 Apache 奇妙的 StringUtils 库,而不是真正的原生 Java。我认为您正在寻找第三方库而不是本机实现。

标签: c#


【解决方案1】:
public static IEnumerable<string> SplitByCharacterType(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentNullException(nameof(input));

    StringBuilder segment = new StringBuilder();
    segment.Append(input[0]);
    var current = Char.GetUnicodeCategory(input[0]);

    for (int i = 1; i < input.Length; i++)
    {
        var next = Char.GetUnicodeCategory(input[i]);
        if (next == current)
        {
            segment.Append(input[i]);
        }
        else
        {
            yield return segment.ToString();
            segment.Clear();
            segment.Append(input[i]);
            current = next;
        }
    }
    yield return segment.ToString();
}

用法如下:

string[] split = SplitByCharacterType("0015j8*(").ToArray();

结果是"0015","j","8","*","("

我建议你作为扩展方法来实现。

【讨论】:

  • +1 做得很好。我自己也尝试过,但结果代码太多了。
  • yield 让一切变得短暂(尽管很慢)。
  • @Mehrdad:性能可以忽略不计。尤其是今天的硬件。如果我在挑剔,我也会使用字符串生成器而不是分段字符串。但是,我实际上认为在这种情况下,在很多情况下它可能会更快。 (而不是直接建立一个列表并返回它)在这种情况下,yield return 实际上是正确和最好的方法。
  • @caesay:是的,抱歉,我的意思是笼统的,不是这个例子。这里的瓶颈在字符串中,而不是在集合中,所以是的,你是对的,你的代码很好。
  • 哇,我完全会让这个实现过于复杂。这个收益回报究竟是如何运作的?它只是退回了一部分,但没有完全退回吗?我假设它是一个 IEnumerable 功能。
【解决方案2】:

我认为这种方法不存在。您可以按照以下步骤创建自己的实用程序方法:

  1. 创建一个列表来保存拆分字符串
  2. 使用所有字符类型定义字符串,例如

     string numberString = "0123456789";
     string specialChars = "~!@#$%^&*(){}|\/?";
     string alphaChars = "abcde....XYZ";
    
  3. 定义一个变量来保存临时字符串
  4. 定义一个变量来记录字符的类型
  5. 遍历您的字符串,一次一个字符,通过检查预定义类型字符串中是否存在 char 来检查 char 的类型。
  6. 如果类型比前一个类型新(检查类型变量值),则将临时字符串(非空)添加到列表中,将新类型分配给类型变量并将当前字符分配给临时字符串。如果不是,则将字符附加到临时字符串。
  7. 在遍历结束时,将临时字符串(非空)添加到列表中
  8. 现在您的列表包含拆分字符串。
  9. 将列表转换为字符串数组即可。

【讨论】:

  • 该方法本身不存在,但是比较字符类型的功能存在。实现所有字符类型类别并逐个检查它们不是一个好主意。
  • 感谢您对实施的概述!
【解决方案3】:

您可以使用正则表达式类,如下所示,但您需要添加对数字和字母以外的其他字符的支持。

   var chars = Regex.Matches("0015j8*(", @"((?:""[^""\\]*(?:\\.[^""\\]*)*"")|[a-z]|\d+)").Cast<Match>().Select(match => match.Value).ToArray(); 

结果 0015,J,8

【讨论】:

  • 我认为这需要太多的体力劳动。在 Java 中实现 splitByCharacterType 支持的所有不同字符类型几乎是不可能的。
  • 总有有人试图用正则表达式回答任何基于文本的问题...叹息
  • 我不知道这里发生了什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 2023-03-31
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
相关资源
最近更新 更多