【问题标题】:Create array of strings from a larger string after delimiting分隔后从较大的字符串创建字符串数组
【发布时间】:2018-07-13 11:23:41
【问题描述】:

我有一个类似于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"] 的字符串数组。目前我正在通过迭代输入字符串手动进行相同的转换。

【问题讨论】:

  • 由于您的字符串中没有固定的分隔符用于拆分,您需要手动迭代和拆分文本
  • 我知道只有两个分隔符'-', '='
  • 但那些也存在于您不需要拆分字符串的地方
  • 是的,这就是为什么我在想是否有一种方法可以将 LINQ 的功能与 split() 相结合来实现这一点。
  • 你考虑过使用正则表达式吗?

标签: c# regex string linq split


【解决方案1】:

你可以使用正则表达式代替拆分吗?

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();

【讨论】:

  • 如果我也想做转换输出如何使用正则表达式 => 输入?
【解决方案2】:

这是一个工作脚本。如果你有一个固定的定界符,你只会看到一个对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

Demo

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

【讨论】:

  • 正如 OP 所说,字符数不固定为 2。
  • @Haytam 我概括了我的答案以涵盖可变数量的字符。
  • 不是 not-have-a-constant-fixed-delimiter 会阻止对 Regex.Split 的单个调用,而是必须复制这些字母。
  • @Rawling 我不明白你的评论,或者你在这里想说什么。如果我的回答有缺陷,请指出。
  • 用字符串ABC-PQ-EFZ=CD-IJ=XYZ-JK测试,最后输出错误XYZ-J JK
【解决方案3】:

对于使用 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();

【讨论】:

    【解决方案4】:

    您可以尝试以下方法: 在这里,我们将根据特殊字符拆分字符串。然后我们将遍历元素并选择直到下一个字符组。 例如:获取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);
                    }
                });
    

    【讨论】:

      【解决方案5】:

      你能适应这样的事情吗?只需要改变分解。

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

      【讨论】:

        【解决方案6】:

        最近在学习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 和模式匹配。

        【讨论】:

          【解决方案7】:
                  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);
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-02-16
            • 1970-01-01
            • 1970-01-01
            • 2017-08-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多