Лучший способ манипулировать и сравнивать строки - PullRequest
1 голос
/ 08 апреля 2010

Я разрабатываю службу REST, поэтому запрос может выглядеть примерно так:

/ Data / Main / Table = Клиенты /

Мне нужно получить сегменты один за другим, и для каждого сегмента я решу, какой объект я собираюсь использовать, после того как я передам этому объекту остальную часть запроса, чтобы он мог решить, что делать дальше , По сути, запрос 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 [] вместо Strings, и реализовать методы, которые я хочу? Или должно быть в порядке с этим? Может быть, регулярные выражения?

UPDATE:

Приведенный выше класс - всего лишь небольшое приближение, я все еще работаю над ним, и мне нужно разобрать более сложные шаблоны.

Я не могу использовать WCF REST или предопределенные пути (например, сопоставить регулярное выражение определенному методу), потому что формат запроса может быть изменен пользователем во время выполнения. Так что надо разбирать шаг за шагом.

Я не могу использовать String.Split, потому что, например, запрос может быть: «Данные / Поиск = '01 / 01/2008 '/ Безотносительно».

Ответы [ 4 ]

8 голосов
/ 08 апреля 2010

Если вы не против его использования. Я бы проверил здесь

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. Затем вы можете выделить переменные после? и выделите каждое выражение запроса, разделив символ &.

string[] uriAndQueryItems = query.Split('?');

if(uriAndQueryItems.Length > 1)
{
   foreach(string queryItem in uriAndQueryItems.Split('&'))
   {
    //do something here.
   }
}
1 голос
/ 08 апреля 2010

Вы можете попробовать регулярное выражение, подобное этому:

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 ...

1 голос
/ 08 апреля 2010

простой - string.split - или я что-то упустил

1 голос
/ 08 апреля 2010

Эта проблема требует регулярных выражений. Вы должны быть в состоянии написать краткое регулярное выражение, чтобы вытащить все группы по этому пути за один раз. Это может быть или не быть быстрее, хотя.

Если вы не измерили это, я действительно сомневаюсь, что это будет для вас каким-то узким местом. Я бы даже не стал беспокоиться об этом, если бы вы не ожидали порядка тысяч разборов в секунду.

(Кстати, я должен был бы предположить, что вам будет гораздо, гораздо приятнее рассматривать ваш путь как IEnumerable<string>, генерирующий каждый уровень пути по очереди, а не иметь класс с внутренним состояние и метод GetNext(), как вы продемонстрировали.)

...