复杂的字符串拆分

Mat*_*ero 11 c# regex string parsing split

我有一个像下面这样的字符串:

[Testing.User]|Info:([Testing.Info]|Name:([System.String]|Matt)|Age:([System.Int32]|21))|Description:([System.String]|This is some description)
Run Code Online (Sandbox Code Playgroud)

您可以将其视为此树:

- [Testing.User]
- Info
        - [Testing.Info]
        - Name
                - [System.String]
                - Matt
        - Age
                - [System.Int32]
                - 21
- Description
        - [System.String]
        - This is some description
Run Code Online (Sandbox Code Playgroud)

如您所见,它是类的字符串序列化/表示 Testing.User

我希望能够进行拆分并在结果数组中获取以下元素:

 [0] = [Testing.User]
 [1] = Info:([Testing.Info]|Name:([System.String]|Matt)|Age:([System.Int32]|21))
 [2] = Description:([System.String]|This is some description)
Run Code Online (Sandbox Code Playgroud)

我不能分开,|因为这会导致:

 [0] = [Testing.User]
 [1] = Info:([Testing.Info]
 [2] = Name:([System.String]
 [3] = Matt)
 [4] = Age:([System.Int32]
 [5] = 21))
 [6] = Description:([System.String]
 [7] = This is some description)
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到预期的结果?

我对正则表达式不太满意,但我知道这是一个非常可能的解决方案.

Fed*_*zza 7

使用正则表达式预测

你可以使用这样的正则表达式:

(\[.*?])|(\w+:.*?)\|(?=Description:)|(Description:.*)
Run Code Online (Sandbox Code Playgroud)

工作演示

此正则表达式背后的想法是在小组捕捉到1,2并且3你想要什么.

您可以使用此图轻松查看:

正则表达式可视化

匹配信息

MATCH 1
1.  [0-14]   `[Testing.User]`
MATCH 2
2.  [15-88]  `Info:([Testing.Info]|Name:([System.String]|Matt)|Age:([System.Int32]|21))`
MATCH 3
3.  [89-143] `Description:([System.String]|This is some description)`
Run Code Online (Sandbox Code Playgroud)

常规正则表达式

另一方面,如果你不喜欢上面的正则表达式,你可以使用另一个这样的:

(\[.*?])\|(.*)\|(Description:.*)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

工作演示

甚至至少强迫一个角色:

(\[.+?])\|(.+)\|(Description:.+)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化


Jen*_*ens 6

已经有足够多的分裂答案,所以这是另一种方法.如果您的输入表示树结构,为什么不将其解析为树?以下代码是从VB.NET自动翻译的,但它应该可以工作到我测试它.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Treeparse
{
    class Program
    {
        static void Main(string[] args)
        {
            var input = "[Testing.User]|Info:([Testing.Info]|Name:([System.String]|Matt)|Age:([System.Int32]|21))|Description:([System.String]|This is some description)";
            var t = StringTree.Parse(input);
            Console.WriteLine(t.ToString());
            Console.ReadKey();
        }
    }

    public class StringTree
    {
        //Branching constants
        const string BranchOff = "(";
        const string BranchBack = ")";
        const string NextTwig = "|";

        //Content of this twig
        public string Text;
        //List of Sub-Twigs
        public List<StringTree> Twigs;
        [System.Diagnostics.DebuggerStepThrough()]
        public StringTree()
        {
            Text = "";
            Twigs = new List<StringTree>();
        }

        private static void ParseRecursive(StringTree Tree, string InputStr, ref int Position)
        {
            do {
                StringTree NewTwig = new StringTree();
                do {
                    NewTwig.Text = NewTwig.Text + InputStr[Position];
                    Position += 1;
                } while (!(Position == InputStr.Length || (new String[] { BranchBack, BranchOff, NextTwig }.ToList().Contains(InputStr[Position].ToString()))));
                Tree.Twigs.Add(NewTwig);
                if (Position < InputStr.Length && InputStr[Position].ToString() == BranchOff) { Position += 1; ParseRecursive(NewTwig, InputStr, ref Position); Position += 1; }
                if (Position < InputStr.Length && InputStr[Position].ToString() == BranchBack)
                    break; // TODO: might not be correct. Was : Exit Do
                Position += 1;
            } while (!(Position >= InputStr.Length || InputStr[Position].ToString() == BranchBack));
        }

        /// <summary>
        /// Call this to parse the input into a StringTree objects using recursion
        /// </summary>
        public static StringTree Parse(string Input)
        {
            StringTree t = new StringTree();
            t.Text = "Root";
            int Start = 0;
            ParseRecursive(t, Input, ref Start);
            return t;
        }

        private void ToStringRecursive(ref StringBuilder sb, StringTree tree, int Level)
        {
            for (int i = 1; i <= Level; i++)
            {
                sb.Append("   ");
            }
            sb.AppendLine(tree.Text);
            int NextLevel = Level + 1;
            foreach (StringTree NextTree in tree.Twigs)
            {
                ToStringRecursive(ref sb, NextTree, NextLevel);
            }
        }

        public override string ToString()
        {
            var sb = new System.Text.StringBuilder();
            ToStringRecursive(ref sb, this, 0);
            return sb.ToString();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

结果(点击):

您可以使用树状结构获取每个节点及其关联子值的值,然后您可以随意使用它,例如在TreeView控件中轻松显示结构:

在此输入图像描述