Как разделить строку, не теряя символы-разделители, используя BCL в C #? - PullRequest
2 голосов
/ 26 июля 2011

Мне нужно разбить строку на основе некоторого символьного массива разделителей и не потерять эти разделители в строке.Т.е.:

string: "Hello world!"
separators: " !"
result: ("Hello", " ", "world", "!")

Конечно, я могу написать что-то, что проходит через эту строку и возвращает мне нужный результат, но разве что-то уже не позволяет мне сделать это, как магически настроенный String.Split?

Upd: Мне нужно решение без регулярного выражения, потому что оно очень медленное для меня.

Ответы [ 3 ]

3 голосов
/ 26 июля 2011

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

string[] parts = Regex.Split(myString, yourPattern);

Тест:

string[] parts = Regex.Split("Hello World!", "(!| )");

Выход:

Hello
" "//just space
World
!
""//empty string
2 голосов
/ 26 июля 2011

Это будет чисто процедурное решение:

private static IEnumerable<string> Tokenize(string text, string separators)
{
    int startIdx = 0;
    int currentIdx = 0;

    while (currentIdx < text.Length)
    {
        // found a separator?
        if (separators.Contains(text[currentIdx]))
        {
            // yield a substring, if it's not empty
            if (currentIdx > startIdx)
                yield return text.Substring(startIdx, currentIdx - startIdx);

            // yield the separator
            yield return text.Substring(currentIdx, 1);

            // mark the beginning of the next token
            startIdx = currentIdx + 1;
        }

        currentIdx++;
    }
}

Обратите внимание, что это решение позволяет избежать возврата пустых токенов. Например, если введено:

string input = "test!!";

вызов Tokenize(input, "!") вернет три токена:

test
!
!

Если требуется, чтобы между двумя соседними разделителями был пустой токен, условие if (currentIdx > startIdx) должно быть удалено.

2 голосов
/ 26 июля 2011

Линк решение:

var s = "Hello world!";
char[] separators = { ' ', '!' };

string current = string.Empty;
List<string> result = s.Aggregate(new List<string>(), (list, ch) =>
    {
        if (separators.Contains(ch))
        {
            list.Add(current);
            list.Add(ch.ToString());
            current = string.Empty;
        }
        else current += ch;
        return list;
    }, list => list);
...