将字符串拆分为字符组的想法

时间:2016-12-14 21:59:46

标签: c# linq parsing

为了测试一般马尔可夫链类,我想将一些文本拆分成字符组。首先,只是元音和辅音组,并最终添加标点符号,或许还有其他人。

我正在寻找有关构建将执行以下操作的功能的想法:

in: "hello", out: { "h", "e", "ll", "o" }
in: "world", out: { "w", "o", "rld" }
in: "Hello world!", out: { "h", "e", "ll", "o", " ", "w", "o", "rld", "!" }

我意识到我可以使用for循环遍历字符数组并通过比较值来构建每个组,但我想知道是否有更简单和/或更快的方法。

我对符合任何以下内容的任何答案感兴趣:

  • 易于实现和阅读,例如简单的linq查询,
  • 演示了一种在其他场景中有用的技术,
  • 表现良好,
  • 依赖一些不常见的功能(我猜第二点相关)。

我正在寻找专门针对C#解决方案,但我会对其他语言的解决方案感兴趣,只要我能翻译它们(即他们不依赖于语言特定功能)。

1 个答案:

答案 0 :(得分:2)

对于示例文本,使用元音和辅音组:

Regex.Split("Hello World","(?<=[aeiou])(?=[^aeiou])|(?<=[^aeiou])(?=[aeiou])|(?<= )")

但是,您的示例输入和输出还显示了对其他两种字符类型(标点符号 - !)和空格的拆分,因此您可以继续编写自己的IEnumberable扩展方法。

void Main()
{
    "Hello World!".it().Dump();
}
public static class StringExtensions
{
    public static IEnumerable<char[]> it(this string s)
    {
        if (string.IsNullOrEmpty(s))
            yield break;

        var z = CharacterClass(s[0]);
        var chars = new List<char>();
        foreach(var c in s)
        {
            var c2=CharacterClass(c);
            if (c2!=z)
            {
                yield return chars.ToArray();
                chars.Clear();
                z=c2;
            }
            chars.Add(c);
        }
        yield return chars.ToArray();
    }

    public static int CharacterClass(char c)
    {
        // 1 = vowel
        // 2 = space characters
        // 3 = punctuation
        // 0 = everything else
        var classes = new Dictionary<char,int> {{'a',1},{'e',1},{'i',1},{'o',1},{'u',1},{' ',2},{'!',3}};
        if (classes.Keys.Contains(c))
        {
            return classes[c];
        }
        return 0;
    }
}