将一个较大的字符串通过分隔符分割后创建一个字符串数组

5
我有一个字符串输入,如下所示var input = "AB-PQ-EF=CD-IJ=XY-JK"。我想知道是否有一种方法可以使用C#和LINQ中的string.split()方法,以便我可以获得一个字符串数组,它看起来像这样var output = ["AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK"]。目前,我正在手动迭代输入字符串进行相同的转换。

1
由于您的字符串没有固定的分隔符,您需要手动迭代和拆分文本。 - Ipsit Gaur
我知道只会有两个分隔符“-”和“=”。 - pango89
但是,这些也存在于您不需要拆分字符串的地方。 - Ipsit Gaur
是的,这就是为什么我在想是否有一种方法可以将LINQ的能力与split()结合起来实现这一点。 - pango89
2
你考虑过使用正则表达式吗? - mnieto
显示剩余2条评论
7个回答

7
你能否使用正则表达式代替分割函数?
var input = "AB-PQ-EF=CD-IJ=XY-JK";
var pattern = new Regex(@"(?<![A-Z])(?=([A-Z]+[=-][A-Z]+))");
var output = pattern.Matches(input).Cast<Match>().Select(m => m.Groups[1].Value).ToArray();

如何在进行转换时使用正则表达式以实现输出 => 输入? - pango89

0

这里有一个可用的脚本。如果您有一个固定的常量分隔符,您只需要调用一次Regex.split。但是您的原始字符串并没有这个,但我们可以在输入中轻松地进行一些重复,使字符串变得可分割。

string input = "ABC-PQ-EF=CD-IJ=XYZ-JK";
string s = Regex.Replace(input, @"((?<=[=-])[A-Z]+(?=[=-]))", "$1~$1");
Console.WriteLine(s);
var items = Regex.Split(s, @"(?<=[A-Z]{2}[=-][A-Z]{2})[~]");
foreach (var item in items)
{
    Console.WriteLine(item);
}

ABC-PQ~PQ-EF~EF=CD~CD-IJ~IJ=XYZ~XYZ-JK
ABC-PQ
PQ-EF
EF=CD
CD-IJ
IJ=XYZ
XYZ-JK

演示

如果您仔细观察上面输出的第一行,您将看到我使用的技巧。我只是通过不同的分隔符(理想情况下, ~ 不会出现在字符串的其他位置)连接您想要的对。然后,我们只需按该分隔符进行拆分。


1
正如楼主所说,字符数量不固定为2个。 - Haytam
@Haytam 我概括了我的答案,以涵盖可变数量的字符。 - Tim Biegeleisen
单次调用 Regex.Split 失败的原因不是缺少固定分隔符,而是需要重复字母。 - Rawling
@Rawling,我不理解你的评论或者你在这里想要表达什么。如果我的回答有缺陷,请指出来。 - Tim Biegeleisen
@Tim,你说“如果你有一个恒定的固定分隔符,你只需要调用一次Regex.split”,我认为你是错误的。即使你只有一个分隔符,你仍然不能使用Split使得输入中的每个字母都出现在输出的两个元素中。相反,如果Split起作用,它可能会处理任意数量的可能分隔符。 - Rawling
显示剩余4条评论

0

对于使用 string.Split 和 LINQ 的解决方案,我们只需要在进行操作时跟踪每个部分的长度,以便可以从原始字符串中提取分隔符,如下所示:

var input = "ABC-PQ-EF=CDED-IJ=XY-JKLM";

var split = input.Split('-', '=');

int offset = 0;

var result = split
            .Take(split.Length - 1)
            .Select((part, index) => {
                offset += part.Length;
                return $"{part}{input[index + offset]}{split[index + 1]}";})
            .ToArray();

0
你可以尝试以下方法: 在这里,我们将根据特殊字符拆分字符串。然后,我们将循环遍历元素并选择直到下一个字符组。 例如:获取AB并获取值直到PQ
        string valentry = "AB-PQ-EF=CD-IJ=XY-JK";
        List<string> filt = Regex.Split(valent, @"[\-|\=]").ToList();

        var listEle = new List<string>();
        fil.ForEach(x => 
            {
                if (valentry .IndexOf(x) != valentry .Length - 2)
                {
                    string ele = valentry.Substring(valentry .IndexOf(x), 5);
                    if (!String.IsNullOrEmpty(ele))
                        listEle.Add(ele);
                }
            });

enter image description here


0

你能否像这样进行调整?只需要更改因式分解。

        List<string> lsOut = new List<string>() { };

        string sInput = "AB-PQ-EF=CD-IJ=XY-JK";
        string sTemp = "";


        for (int i = 0; i < sInput.Length; i++)
        {

            if ( (i + 1) % 6 == 0)
            {
                continue;
            }

            // add to temp
            sTemp += sInput[i];

            // multiple of 5, add all the temp to list
            if ( (i + 1 - lsOut.Count) % 5 == 0)
            {
                lsOut.Add(sTemp);
                sTemp = "";
            }

            if(sInput.Length == i + 1)
            {
                lsOut.Add(sTemp);
            }

        }

0
        string input = "AB-PQ-EF=CD-IJ=XY-JK";
        var result = new Regex(@"(?<![A-Z])(?=([A-Z]+[=-][A-Z]+))").Matches(input)
            .Cast<Match>().Select(m => m.Groups[1].Value).ToArray();
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }

0

最近在学习 Haskell,所以这里提供了一个递归解决方案。

static IEnumerable<string> SplitByPair(string input, char[] delimiter)
{
    var sep1 = input.IndexOfAny(delimiter);
    if (sep1 == -1)
    {
        yield break;
    }
    var sep2 = input.IndexOfAny(delimiter, sep1 + 1);
    if (sep2 == -1)
    {
        yield return input;
    }
    else
    {
        yield return input.Substring(0, sep2);
        foreach (var other in SplitByPair(input.Substring(sep1 + 1), delimiter))
        {
            yield return other;
        }
    }
}

好处有:

  • 它很懒
  • 容易扩展到其他条件和其他数据类型。但是在C#中有点困难,因为C#缺乏Haskell的List.span和模式匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接