根据分界符分开单词

时间:2018-01-10 08:21:00

标签: c# regex split delimiter

我有一个搜索框,允许搜索表格中的内容(以空格分隔)和搜索表格中的特定字段(冒号分隔)。

唯一的问题是这些都可以同时存在。 例子:

  1. 类型:非小说谋杀
  2. 非ISBN:000000001
  3. 小说ISBN:02 Plane
  4. 从示例1开始,Type是字段名称,Non-Fiction是其内容,Murder是任何字段中的内容。我正在寻找一个Regex.Split,它将字段:结果放入一个Dictionary,将任何其他结果放入一个数组中。

    我设法让两者分开工作但不混合:

    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:000000001 Kill

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

2 个答案:

答案 0 :(得分:2)

如果你愿意放弃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);
}

基本上在空格上分词,然后在冒号上分开它们。

如果您真的想要一个内容数组而不是List,只需执行contents.ToArray()

答案 1 :(得分:2)

我不明白为什么使用Regex会更快。恕我直言,我认为使用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;
    }
}

现在,如果您愿意使用简单的Regex匹配,而不是使用Regex.Split()方法,则可能会认为这稍微更易读/可维护:

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