Разбить строку оставив разделители

149
03 июня 2019, 02:20

Как из строки с предложением сделать массив слов, содержащий слова и пробелы в C#? Например, из строки "I walk with" должен получиться массив, содержащий {"I", " ", "walk", " ", "with"}. Можно ли это сделать при помощи Split?

Answer 1

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

Regex.Split("I walk with", "( +)") вернёт то, что Вы хотите получить.

public static class StrExtension
{
    public static string[] SplitAndKeepDelimiters2(this string str, char delimiter)
    {
        return Regex.Split(str, $"({Regex.Escape(delimiter.ToString())}+)");
    }
}
Answer 2

Как ни странно, но вот такая вот конструкция справится с поставленной задачей:

public static class StrExtension
{
    public static string[] SplitAndKeepDelimiters(this string str, char delimiter)
    {
        var nullChar = (char)0;
        return str.Replace($"{delimiter}", $"{nullChar}{delimiter}{nullChar}")
                  .Split(nullChar);
    }
}

В чем логика: мы делаем вот это:

return str.Replace(" ", "| |").Split('|');

только заменив |на null-символ ASCII, который 100% не будет в тексте встречаться. :)

Проще данного подхода, наверное и не бывает.

Answer 3

не претендующий на звание "скоростного", Linq-вариант:

"I walk with"
    .Split(' ')
    .SelectMany(it => new[] { " ", it })
    .Skip(1)
Answer 4

Самый простой вариант - так:

public static IList<string> SplitAndKeepDelimiters(this string s, params char[] delimiters)
{
    var parts = new List<string>();
    if (!string.IsNullOrEmpty(s))
    {
        int iFirst = 0;
        do
        {
            int iLast = s.IndexOfAny(delimiters, iFirst);
            if (iLast >= 0)
            {
                if (iLast > iFirst)
                    parts.Add(s.Substring(iFirst, iLast - iFirst)); //part before the delimiter
                parts.Add(new string(s[iLast], 1));//the delimiter
                iFirst = iLast + 1;
                continue;
            }
            //No delimiters were found, but at least one character remains. Add the rest and stop.
            parts.Add(s.Substring(iFirst, s.Length - iFirst));
            break;
        } while (iFirst < s.Length);
    }
    return parts;
}

Например:

var source = "I walk with";
var result = source.SplitAndKeepDelimiters(' ');

Больше вариантов - тут:

  • Split a string with delimiters but keep the delimiters in the result in C#
Answer 5

Можно вот так вот:

var separator = ' ';
var res = new List<string>();
var testStr= "I walk d with";
testStr.Split(separator).ToList().ForEach(x =>
{
    if (res.Any()&&x != string.Empty&&res.Last()!=separator.ToString()) 
        res.Add(separator.ToString());
    res.Add(x==string.Empty? separator.ToString():x);
});
READ ALSO
Изменение шрифта отдельных слов в TreeView

Изменение шрифта отдельных слов в TreeView

Пишу программу, в которой необходимо в TreeView (в узлах всех уровней) выделять отдельные слова, указанные в словаре, жирным шрифтомПоискав решение...

138
Вставить картинку в тело письма

Вставить картинку в тело письма

Вопрос такой, как вставить картинку в тело сообщения? Искал в интернете, находил AlternateView jpeg_view = new AlternateView, но не помогаетсообщение на почте...

160
Возможные проблемы с модификатором in

Возможные проблемы с модификатором in

Читал про новые фичи C# и ключевое слово in для параметров

160
Как обобщить наследуемые объекты COM?

Как обобщить наследуемые объекты COM?

Базовый класс для всех COM объектов:

175