操纵和比较字符串的最佳方法

时间:2010-04-08 17:56:01

标签: c# .net string

我正在开发一个REST服务,所以请求可能是这样的:

/数据/主/表=客户/

我需要逐个获取片段,对于每个片段,我将决定我将要使用的对象,在我将查询的其余部分传递给该对象后,它可以决定下一步做什么。基本上,REST查询是树上的路径:P

这意味着很多String操作(取决于查询的复杂性),但StringBuilder仅用于连接和删除,你不能用IndexOf或类似的搜索执行。

我开发了这个满足我要求的类,但问题是操作字符串,所以每次我得到一个段......我会创建额外的字符串,因为String是一个不可改变的数据类型:

public class RESTQueryParser
{
    String _query;

    public RESTQueryParser(String query)
    {
        _query = query;
    }

    public String GetNext()
    {
        String result = String.Empty;
        Int32 startPosition = _query.StartsWith("/", StringComparison.InvariantCultureIgnoreCase) ? 1 : 0;

        Int32 i = _query.IndexOf("/", startPosition, StringComparison.InvariantCultureIgnoreCase) - 1;

        if (!String.IsNullOrEmpty(_query))
        {
            if (i < 0)
            {
                result = _query.Substring(startPosition, _query.Length - 1);
                _query = String.Empty;
            }
            else
            {
                result = _query.Substring(startPosition, i);
                _query = _query.Remove(0, i + 1);
            }
        }

        return result;
    }
}

服务器应该支持很多调用,查询可能很大,所以这将是一个非常重复的任务。我真的不知道对内存和性能的影响有多大,我只是在一些书中对它进行了研究。

我应该实现一个管理Char []的类而不是字符串并实现我想要的方法吗?或者应该对这个好吗?正则表达式可能吗?

更新:

上面的类只是一个小的aproximation,我还在研究它,我必须解析更复杂的模式。

我无法使用WCF REST或预定义路径(例如将正则表达式映射到特定方法),因为用户可以在运行时更改查询格式。所以必须逐步解析。

我不能使用String.Split,因为例如查询可能是:“Data / Search = '01 / 01/2008'/ Whatever”。

4 个答案:

答案 0 :(得分:8)

除非你反对使用它。我会在这里查看

http://msdn.microsoft.com/en-us/netframework/cc950529.aspx

WCF为您处理REST实现。无需解析URL。

如果您必须手动解析查询,我会使用

string[] queryParts = query.Trim('/').Split('/');

您可以单独浏览每个部分,而无需使用IndexOf。

String.Split方法: http://msdn.microsoft.com/en-us/library/system.string.split.aspx

如果您不打算使用WCF并且它是REST实现,那么您要做的是将您的变量信息放在查询字符串参数中

/Data/Main/Table=Customers/  

确实需要:

/Data/Main?Table=Customers

/Data/Main/Table/Customers

您将需要一种方法将路径路径与查询变量分开。复杂性需要是查询字符串的一部分,而不是基本URI的一部分。然后你可以把变量分开出去?并通过拆分&amp;。

来分离出每个查询表达式
string[] uriAndQueryItems = query.Split('?');

if(uriAndQueryItems.Length > 1)
{
   foreach(string queryItem in uriAndQueryItems.Split('&'))
   {
    //do something here.
   }
}

答案 1 :(得分:1)

这个问题引发了正则表达式。您应该能够编写一个简洁的正则表达式,一次性拉出该路径中的所有组。但它可能会或可能不会更快。

如果你还没有测量过,我真的怀疑这对你来说是个什么样的瓶颈。我甚至不会考虑担心它,除非你期望每秒数千次解析。

(顺便说一句,我不得不想象,将你的路径视为IEnumerable<string>会更加愉快,依次产生路径的每个级别,而不是拥有一个类正如您所演示的那样,使用内部状态和GetNext()方法。)

答案 2 :(得分:1)

简单的是string.split - 或者我错过了什么

答案 3 :(得分:1)

您可以尝试这样的正则表达式:

var input = "/Data/Main/Table=Customers/";
var regex = new Regex(@"\w+?/");
var matches = regex.Matches(input);
foreach (var match in matches)
{
    Console.WriteLine(match.ToString());
}
Console.ReadKey();

另外,您可以查看System.Web.Routing命名空间...