C # Разбор текста в кавычках - PullRequest
1 голос
/ 15 октября 2010

Я занимаюсь разработкой простого небольшого поискового механизма и хочу позволить пользователю искать фрагменты текста с пробелами. Например, пользователь может искать имя человека:

Имя: John Smith

I затем "John Smith".Split(' ') в массив из двух элементов, {"John","Smith"}. Затем я возвращаю все записи, которые соответствуют «Джону» и «Смиту», затем следуют записи, которые соответствуют либо "John" OR "Smith.". Затем я не возвращаю записей для совпадений. Это не сложный сценарий, и эта часть у меня работает.

Теперь я хотел бы иметь возможность разрешать пользователю ТОЛЬКО возвращать записи, соответствующие «Джону Смиту»

Я бы хотел использовать синтаксис базовой цитаты для поиска. Поэтому, если пользователь хочет найти «Джон Смит» ИЛИ Покахонтас, он должен ввести: «Джон Смит» Покахонтас. Порядок условий абсолютно не имеет значения; «Джон Смит» не получает приоритета над Покахонтасом, потому что он стоит первым в списке.

У меня есть две основные мысли о том, как мне анализировать входные данные.

A) Using regular expression then parsing stuff (IndexOf, Split)
B) Using only the parsing methods 

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

Как мне найти совпадения из регулярного выражения? Я знаю о regex.Replace, но как бы мне перебрать совпадения и вставить их в список. Я знаю, что есть некоторый изящный способ сделать это, используя делегат MatchEvaluator и linq, но я практически ничего не знаю о регулярных выражениях в c #.

Ответы [ 3 ]

1 голос
/ 15 октября 2010

РЕДАКТИРОВАТЬ: Вернулся на эту вкладку без обновления и не понял, что на этот вопрос уже был дан ответ ... принятый ответ лучше.


Я думаю, хорошая идея - сначала вытянуть материал в кавычках с помощью регулярных выражений. Может быть, что-то вроде этого:

String sampleInput = "\"John Smith\" Pocahontas Bambi \"Jane Doe\" Aladin";

//Create regex pattern
Regex regex = new Regex("\"([^\".]+)\"");

List<string> searches = new List<string>();

//Loop through all matches from regex
foreach (Match match in regex.Matches(sampleInput))
{
    //add the match value for the 2nd group to the list
    //(1st group is the entire match)
    //(2nd group is the first parenthesis group in the defined regex pattern
    //   which in this case is the text inside the quotes)
    searches.Add(match.Groups[1].Value);
}

//remove the matches from the input
sampleInput = regex.Replace(sampleInput, String.Empty);

//split the remaining input and add the result to our searches list
searches.AddRange(sampleInput.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries));
0 голосов
/ 06 мая 2014

Мне нужна была та же функциональность, что и у Шона, но я не хотел использовать регулярные выражения.Вот простое решение, которое я придумал, использует Split () вместо regex для тех, кому нужна эта функциональность.

Это работает, потому что метод Split по умолчанию создает пустые записи в массиве для последовательного поисказначения в исходной строке.Если мы разделим символ кавычки, то результатом будет массив, в котором четные индексированные записи будут отдельными словами, а нечетные индексированные записи будут фразами в кавычках.

Пример:

“John Smith” Pocahontas

Результатыв

item(0) = (empty string)
item(1) = John Smith
item(2) = Pocahontas

И

1 2 “3 4” 5 “6 7” “8 9”

Результаты в

item(0) = 1 2
item(1) = 3 4
item(2) = 5
item(3) = 6 7
item(4) = (empty string)
item(5) = 8 9

Обратите внимание, что непревзойденная цитата приведет к фразе из последней цитаты до концавходная строка.

    public static List<string> QueryToTerms(string query)
    {
        List<string> Result = new List<string>();

        // split on the quote token
        string[] QuoteTerms = query.Split('"');
        // switch to denote if the current loop is processing words or a phrase
        bool WordTerms = true;

        foreach (string Item in QuoteTerms)
        {
            if (!string.IsNullOrWhiteSpace(Item))
                if (WordTerms)
                {
                    // Item contains words. parse them and ignore empty entries.
                    string[] WTerms = Item.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string WTerm in WTerms)
                        Result.Add(WTerm);
                }
                else
                    // Item is a phrase.
                    Result.Add(Item);

            // Alternate between words and phrases.
            WordTerms = !WordTerms;
        }
        return Result;
    }
0 голосов
/ 15 октября 2010

Используйте регулярное выражение так:

string input = "\"John Smith\" Pocahontas";
Regex rx = new Regex(@"(?<="")[^""]+(?="")|[^\s""]\S*");
for (Match match = rx.Match(input); match.Success; match = match.NextMatch()) {
    // use match.Value here, it contains the string to be searched
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...