根据模式从字符串中提取值

时间:2019-11-18 19:34:18

标签: c#

我需要根据预定义的模式从字符串中提取一堆键值对。我需要的一个例子是:

模式:{value1}-{value2}

字符串:示例字符串

结果KVP:

ChildComponent

要注意的是,该模式几乎可以是任何东西(尽管我需要提取的值始终用大括号括起来),即:

模式:{test1} \ {test2} = {value}

字符串:Example \ Value = Result

结果KVP:

{ Key: value1, value: Example },
{ Key: value2, value: String }

到目前为止,我所做的工作还不够完善,我可以肯定的是,无论如何,与我的解决方案相比,都必须有一种更优雅的方式来做到这一点,所以我想我可以看看这里是否有人一个好主意。

编辑:

到目前为止,这基本上是我所拥有的(它正在工作,但是IMO确实很丑陋):

{ Key: test1, value: Example },
{ Key: test2, value: Value },
{ Key: value, value: Result }

1 个答案:

答案 0 :(得分:1)

不幸的是,我对正则表达式不太了解,但是解决此问题的一种方法是遍历pattern字符串的每个字符并创建keysdelimeters的列表,之后我们可以遍历search字符串,找到每个delimeter的索引来获取当前的value,然后将新的KeyValuePair添加到列表中。

这里有一个粗略的示例,假设输入很好:

public static List<KeyValuePair<string, string>> GetKVPs(string pattern, string search)
{
    var results = new List<KeyValuePair<string, string>>();
    var keys = new List<string>();
    var delimeters = new List<string>();
    var currentKey = string.Empty;
    var currentDelimeter = string.Empty;
    var processingKey = false;

    // Populate our lists of Keys and Delimeters
    foreach (var chr in pattern)
    {
        switch (chr)
        {
            case '}':
            {
                if (currentKey.Length > 0)
                {
                    keys.Add(currentKey);
                    currentKey = string.Empty;
                }

                processingKey = false;
                break;
            }
            case '{':
            {
                if (currentDelimeter.Length > 0)
                {
                    delimeters.Add(currentDelimeter);
                    currentDelimeter = string.Empty;
                }

                processingKey = true;
                break;
            }
            default:
            {
                if (processingKey)
                {
                    currentKey += chr;
                }
                else
                {
                    currentDelimeter += chr;
                }
                break;
            }
        }
    }

    if (currentDelimeter.Length > 0) delimeters.Add(currentDelimeter);

    var lastDelim = -1;

    // Find our Values based on the delimeter positions in the search string
    for (int i = 0; i < delimeters.Count; i++)
    {
        var delimIndex = search.IndexOf(delimeters[i], lastDelim + 1);

        if (delimIndex > -1)
        {
            var value = search.Substring(lastDelim + 1, delimIndex - lastDelim - 1);
            results.Add(new KeyValuePair<string, string>(keys[i], value));
            lastDelim = delimIndex + delimeters[i].Length - 1;
        }
    }

    // Add the item after the final delimeter if it exists:
    if (lastDelim > -1 && lastDelim < search.Length - 1)
    {
        results.Add(new KeyValuePair<string, string>(keys.Last(),
            search.Substring(lastDelim + 1)));
    }

    return results;
}

以及运行中的示例:

public static void Main(string[] args)
{
    var results = GetKVPs(
        "{greeting}, {recipient}, this is {sender}.", 
        "Hello, Dolly, this is Louis.");

    foreach (var kvp in results)
    {
        Console.WriteLine($"{kvp.Key} = {kvp.Value}");
    }

    GetKeyFromUser("\nDone! Press any key to exit...");
}

输出

enter image description here