linq 如何根据字符拆分同一字符串?

bxpogfeg  于 2022-12-06  发布在  其他
关注(0)|答案(2)|浏览(270)

我希望能够从一个给定的字符串中创建一个字符串数组。**()之间的字符应该是一个元素,()**之外的每个字符应该同样计数。因此,一个字符串如下:

string test = "(af)sd(abc)abc"

将生成如下所示数组:

string[] testSplitted = { "af", "s", "d", "abc", "a", "b", "c" };

下面的代码只能生成数组中**()项内的字符,而不能生成()项外的字符。因此,我得到:
第一次
有没有办法把
()**之外的字符也拆分成不同的元素?

um6iljoc

um6iljoc1#

这是一个非常简单的状态机,它的时间复杂度是O(n)。

public static IEnumerable<string> StringWalker(string input)
{
    bool inParens = false;
    StringBuilder buffer = new StringBuilder();
    List<string> result = new List<string>();

    foreach (var c in input)
    {
        if (c == '(')
        {
            if (inParens)
            {
                throw new Exception("Nested Parens not allowed");
            }
            inParens = true;
            buffer.Clear();
        }
        else if (inParens)
        {
            if (c == ')')
            {
                inParens = false;
                result.Add(buffer.ToString());
            }
            else
            {
                buffer.Append(c);
            }
        }
        else
        {
            result.Add(c.ToString());
        }
    }
    return result;
}

结果如下:

abc(de)(fgh)ijk:  ==>  (a) (b) (c) (de) (fgh) (i) (j) (k) 
(abc)de(f)gh(ijklm)nop:  ==>  (abc) (d) (e) (f) (g) (h) (ijklm) (n) (o) (p)
k5ifujac

k5ifujac2#

You can try using reguar expressions and Match all the items:

using System.Linq;
using System.Text.RegularExpressions;

...

string test = "(af)sd(abc)abc";

string[] testSplitted = Regex
  .Matches(test, @"\(.*?\)|.")
  .Cast<Match>()
  .Select(match => match.Value.Trim('(', ')'))
  .ToArray();

Pattern explained:

\(.*?\) - zero or more characters (aw few as possible) within (...)
  |       - OR
  .       - single character

More tests:

string[] tests = new string[] {
  "(ab)(bc)(ca)", 
  "abc", 
  "(abc)(abc)(abc)", "(zyx)bc" 
};

static string[] Perform(string value) => Regex
  .Matches(value, @"\(.*?\)|.")
  .Cast<Match>()
  .Select(match => match.Value.Trim('(', ')'))
  .ToArray();

string report = string.Join(Environment.NewLine, tests
  .Select(test => $"{test,15} => {string.Join(", ", Perform(test))}"));

Console.Write(report);

Output:

(ab)(bc)(ca) => ab, bc, ca
            abc => a, b, c
(abc)(abc)(abc) => abc, abc, abc
        (zyx)bc => zyx, b, c

Please, fiddle yourself

相关问题