linq 将字符串拆分为字符组的方法

ibps3vxo  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(127)

为了测试一个通用的马尔可夫链类,我想把一些文本分成字符组。首先,只有元音和辅音组,最后添加标点符号,也许其他。
我正在寻找关于构建一个函数的想法,该函数将执行以下操作:

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#解决方案,但我会对其他语言的解决方案感兴趣,只要我可以翻译他们(即,他们不依赖于语言特定的功能)。

myzjeezk

myzjeezk1#

对于包含元音和辅音组的示例文本:

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

但是,示例输入和输出还显示了其他两种字符类型(标点符号-!)和空格上的拆分,因此,您不妨直接编写一个IEnumerable扩展方法。

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;
    }
}

相关问题