C# 按delimeter分开单词

C# 按delimeter分开单词,c#,regex,split,delimiter,C#,Regex,Split,Delimiter,我有一个搜索框,既可以搜索表中的内容(以空格分隔),也可以搜索表中的特定字段(以冒号分隔) 唯一的问题是,这两者可能同时存在。 示例: 类型:非虚构谋杀 非ISBN:00000000 1 小说ISBN:02飞机 从示例1中,Type是字段名,Non-Fiction是其内容,而谋杀是任何字段中的内容。我正在寻找一个Regex.Split,它将字段:result放入字典,将任何其他结果放入数组 我已设法使这两项工作在单独的基础上进行,但没有混合: var columnSearch_FieldName

我有一个搜索框,既可以搜索表中的内容(以空格分隔),也可以搜索表中的特定字段(以冒号分隔)

唯一的问题是,这两者可能同时存在。 示例:

  • 类型:非虚构谋杀
  • 非ISBN:00000000 1
  • 小说ISBN:02飞机
  • 从示例1中,Type是字段名,Non-Fiction是其内容,而谋杀是任何字段中的内容。我正在寻找一个Regex.Split,它将字段:result放入字典,将任何其他结果放入数组

    我已设法使这两项工作在单独的基础上进行,但没有混合:

    var columnSearch_FieldNames = inSearch.ToUpper().Trim().Split(':').Where((x,i) => i % 2 == 0).ToArray();
    var columnSearch_FieldContent = inSearch.ToUpper().Trim().Split(':').Where((x, i) => i % 2 != 0).ToArray();
    var adhocSearch_FieldContent = inSearch.ToUpper().Trim().Split(' ');
    
    示例4:-类型:非虚构谋杀非ISBN:00000000 1杀人

    示例输出:-字典({Type,Non-Fiction},{ISBN,0000001})
    数组{killer,Non,Kill}

    如果您愿意放弃
    Regex
    以获得一个结合了多个拆分的好的旧foreach循环,我认为这就实现了您想要的:

    Dictionary<string, string> fields = new Dictionary<string, string>();
    List<string> contents = new List<string>();
    
    foreach (var word in main.Split(' '))     //main is a string, e.g. "Type:Non-Fiction Murder Non ISBN:000000001 Kill"
    {
        var splitted = word.Split(':');
        if (splitted.Length == 2)
        {
            fields.Add(splitted[0], splitted[1]);
            continue;
        }
        contents.Add(word);
    }
    
    字典字段=新字典();
    列表内容=新列表();
    foreach(main.Split(“”)中的var word//main是一个字符串,例如“Type:Non-虚构谋杀Non-ISBN:00000000 1 Kill”
    {
    var splitted=word.Split(“:”);
    如果(拆分的长度==2)
    {
    添加(拆分的[0],拆分的[1]);
    继续;
    }
    内容。添加(word);
    }
    
    基本上是在空格上拆分单词,然后在冒号上拆分它们


    如果您确实想要一个内容数组而不是
    列表
    ,只需执行
    contents.ToArray()

    我不明白为什么使用
    正则表达式会更快。恕我直言,使用
    Regex
    ,我认为代码的可读性或可维护性没有任何改善。如果有的话,我想会更复杂。但是,如果您真的想使用
    Regex.Split()
    ,类似这样的方法可以:

    static void Main(string[] args)
    {
        string input = "Type:Non-Fiction Murder Non ISBN:000000001 Kill", key = null, value = null;
        Dictionary<string, string> namedFields = new Dictionary<string, string>();
        List<string> anyField = new List<string>();
        Regex regex = new Regex("( )|(:)", RegexOptions.Compiled);
    
        foreach (string field in regex.Split(input))
        {
            switch (field)
            {
                case " ":
                    _AddParameter(ref key, ref value, namedFields, anyField);
                    break;
                case ":":
                    key = value;
                    break;
                default:
                    value = field;
                    break;
            }
        }
        _AddParameter(ref key, ref value, namedFields, anyField);
    }
    
    private static void _AddParameter(ref string key, ref string value, Dictionary<string, string> namedFields, List<string> anyField)
    {
        if (key != null)
        {
            namedFields.Add(key, value);
            key = null;
        }
        else if (value != null)
        {
            anyField.Add(value);
            value = null;
        }
    }
    

    这会将字段:result放入字典,将任何其他结果放入数组>我不明白。你能给出一个输出示例吗?我不明白你为什么需要正则表达式。为什么不先在空格上拆分,然后使用冒号拆分每个结果?(顺便说一句,您不应该使用
    ToUpper()
    ToLower()
    来实现不区分大小写的搜索。使用带有
    StringComparison
    enum值的适当比较方法。)完成@PatrickHofman。“如果还不清楚的话,我会重新措辞。”彼得杜尼奥同意托珀的说法。我认为可能有一种方法可以一次完成操作,因此使用正则表达式拆分,而不必再次解析拆分的单词。是的,这也可以做到。我相信Regex.Split版本会稍微快一点。我赞成投票,因为它肯定有用。谢谢你底部的那一个正是我想的,而且是如何建造它的珍品。我认为拆分会自动将相应的单词放入适当的列表中。谢谢Peter,做得好。嗨,如果我想要这个正则表达式的更新版本包含其他匹配项,我应该编辑我的原始问题吗?请引导我。谢谢。“我应该编辑我的原始问题吗?”--不,编辑你的问题以提出不同的问题是不合适的。如果希望包含其他匹配项,则应采取的第一步是尝试修改现有解决方案以适应新需求。如果在尝试之后,您无法发布一个新问题,并附上一个好的标题,说明您尝试了什么,解释代码的作用,您希望它做什么,以及您自己无法理解的具体内容。谢谢。虽然我的正则表达式知识非常有限,但我还是按照你的建议管理了自己。这个新的数组应该进一步将方括号中的“FieldValue”放在一个单独的数组中。(?:(?[^ ]+):(?(\[[^_[]+])+))|(?:(?[^ ]+):(?[^ ]+))|(?[^ ]+)
    private static void UsingRegex(string input)
    {
        Dictionary<string, string> namedFields = new Dictionary<string, string>();
        List<string> anyField = new List<string>();
        Regex regex = new Regex("(?:(?<key>[^ ]+):(?<value>[^ ]+))|(?<loneValue>[^ ]+)", RegexOptions.Compiled);
    
        foreach (Match match in regex.Matches(input))
        {
            string key = match.Groups["key"].Value,
                value = match.Groups["value"].Value,
                loneValue = match.Groups["loneValue"].Value;
    
            if (!string.IsNullOrEmpty(key))
            {
                namedFields.Add(key, value);
            }
            else
            {
                anyField.Add(loneValue);
            }
        }
    }