Извлечь все вхождения определенных символов из строк - PullRequest
3 голосов
/ 02 апреля 2012

У меня есть что-то вроде этого в моем коде.

mystring.Split(new[]{"/","*"}, StringSplitOptions.RemoveEmptyEntries);

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

Я мог бы использовать .IndexOf для продолжения поиска, пока не извлеку все из них, но почему-то я думаю, что это будет излишним.Есть ли способ сделать это в .NET?Если возможно, я хочу избежать LINQ.

Спасибо.

Ответы [ 5 ]

4 голосов
/ 02 апреля 2012

Что-то вроде:

var separators = new char[] { '/', '*' };
var words = new List<string>();
var delimiters = new List<string>();
var idx = source.IndexOfAny(separators);
var prevIdx = 0;
while (idx > -1)
{
    if (idx - prevIdx > 0)
        words.Add(source.Substring(prevIdx, idx - prevIdx));

    prevIdx = idx + 1;
    delimiters.Add(source.Substring(idx, 1));
    idx = source.IndexOfAny(separators, idx + 1);
}
2 голосов
/ 02 апреля 2012

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

Я думаю, что следующий код будет работать:

        List<string> SeparatedItems = new List<string>();
        List<string> Delimiters = new List<string>();

        string sTestString = "mytest/string*isthis**and not/this";

        string sSeparatedItemString = String.Empty;
        foreach(char c in sTestString) {

            if(c == '/' || c == '*') {

                Delimiters.Add(c.ToString());
                if(sSeparatedItemString != String.Empty) {

                    SeparatedItems.Add(sSeparatedItemString);
                    sSeparatedItemString = String.Empty;  
                }
            }
            else {

                sSeparatedItemString += c.ToString();    
            }   

        }

        if(sSeparatedItemString != String.Empty) {

            SeparatedItems.Add(sSeparatedItemString);
        }
1 голос
/ 02 апреля 2012

Попробуйте это:

var items = new List<string>();
var delimiters = new List<string>();
items.AddRange(Regex.Split(text, @"(?<=/)|(?=/)|(?<=\*)|(?=\*)"));

for (int i = 0; i < items.Count; )
{
    string item = items[i];
    if (item == "*" || item == "/")
    {
        delimiters.Add(item);
        items.RemoveAt(i);
    }
    else if (item == "")
    {
        items.RemoveAt(i);
    }
    else
    {
        i++;
    }
}
0 голосов
/ 02 апреля 2012

Поскольку вы работаете в .NET 2.0, я бы сказал, что использование IndexOf - это один из самых простых способов решения проблемы:

public static int CountOccurences(string input, string pattern)
{
    int count = 0;
    int i = 0;

    while (i = input.IndexOf(pattern, i) != -1)
        count++;
    return count;
}

Решение, которое предлагает Роб Смит, такжеработать, но я считаю это самым простым и понятным.

0 голосов
/ 02 апреля 2012

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

...