Как разбить строку в C # - PullRequest
4 голосов
/ 09 мая 2011

У меня есть строка типа

"List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar"

и List<String> как

 List<String> l_lstValues = new List<string> { "List_1", "XList_3", "List_2" };

Мне нужно разбить строку на основе значения в l_lstValues.

Таким образом, разделенные подстроки будут иметь вид

List_1 fooo asdf 
List_2 bar fdsa 
XList_3 fooo bar

Пожалуйста, напишите мне способ сделать это Заранее спасибо

Ответы [ 8 ]

3 голосов
/ 09 мая 2011

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

Я оставляю вам ссылку здесь

http://msdn.microsoft.com/en-us/library/tabh47cf(v=VS.90).aspx

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

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

Увидимся

1 голос
/ 09 мая 2011

Вы можете сделать что-то вроде этого:

            string a = "List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar";
            List<String> l_lstValues = new List<string> { "List_1", 
                                                      "XList_3", "List_2" };

            var e = l_lstValues.GetEnumerator();
            e.MoveNext();
            while(e.MoveNext())
            {
                var p = a.IndexOf(e.Current);
                a = a.Insert(p, "~");
            }
            var splitStrings = a.Split(new string[]{" ~"},StringSplitOptions.None);

Итак, я вставляю ~ всякий раз, когда сталкиваюсь с элементом из списка (за исключением первого, следовательно, внешнего e.MoveNext()), а затем делю на ~ (обратите внимание на предыдущее пространство) что у вас нет ~ в строке, но я думаю, что это решение достаточно простое, если вы можете найти такой символ и убедиться, что символ не появится в исходной строке. Если символ не работает для вас, используйте что-то вроде ~~@@, и так как мое решение показывает разделение строки с string[], вы можете просто добавить всю строку для разделения.

Конечно, вы можете сделать что-то вроде:

foreach (var sep in l_lstValues)
        {
            var p = a.IndexOf(sep);
            a = a.Insert(p, "~");

        }

но там будет пустая строка, и мне просто нравится использовать MoveNext() и Current:)

1 голос
/ 09 мая 2011

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

List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar

должна стать:

List_1 fooo asdf;List_2 bar fdsa;XList_3 fooo bar

, которая впоследствии будет разбита на основе ;, что приведет к желаемому результату.Для этого я использую этот код:

string ori = "List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar" 
foreach (string word in l_lstValues) {
    ori = ori.Replace(word, ";" + word);
}
ori = ori.Replace(" ;", ";"); // remove spaces before ;
ori = Regex.Replace(ori, "^;", ""); // remove leading ;
return (ori.split(";"));

Вы также можете собрать следующее регулярное выражение:

(\S)(\s?(List_1|XList_3|List_2))

Первый токен (\S) предотвратит замену первого вхождения, авторой токен \s? удалит пробел.Теперь мы используем его для добавления ;:

string ori = "List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar" 
string regex = "(\S)(\s?(" + String.Join("|", l_lstValues) + "))";
ori = Regex.Replace(ori, regex, "$1;$3");
return (ori.split(";"));

Опция regex немного более опасна, поскольку слова могут содержать последовательности scape.

1 голос
/ 09 мая 2011

Вот самое простое и понятное решение:

    public static string[] Split(string val, List<string> l_lstValues) {
        var dic = new Dictionary<string, List<string>>();
        string curKey = string.Empty;
        foreach (string word in val.Split(' ')) {
            if (l_lstValues.Contains(word)) {
                curKey = word;
            }
            if (!dic.ContainsKey(curKey))
                dic[curKey] = new List<string>();
            dic[curKey].Add(word);
        }
        return dic.Values.ToArray();
    }

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

РЕДАКТИРОВАТЬ: Я просто нашел исходный ответ, чтобы больше соответствовать вопросу.Теперь он возвращает массив string [] - так же, как и метод String.Split ().Исключение будет выдано, если последовательность входящих строк не начинается с ключа из списка l_lstValues.

1 голос
/ 09 мая 2011

Вы можете сделать что-то вроде ниже:

string sampleStr = "List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar";
string[] splitStr = 
   sampleStr.Split(l_lstValues.ToArray(), StringSplitOptions.RemoveEmptyEntries);

РЕДАКТИРОВАТЬ : Модифицировано для печати фрагментов также со словом списка

Предположение : в 1011 *

нет ':'
foreach(string listWord in l_lstValues)
{
    sampleStr = sampleStr.Replace(listWord, ':'+listWord);
}
string[] fragments = sampleStr.Split(':');
0 голосов
/ 09 мая 2011

Вы можете использовать следующий код для выполнения этой задачи

        string str = "List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar";
        List<String> l_lstValues = new List<string> { "List_1", "XList_3", "List_2" };

        string[] strarr = str.Split(' ');
        string sKey, sValue;
        bool bFlag = false;
        sKey = sValue = string.Empty;

        var lstResult = new List<KeyValuePair<string, string>>();

        foreach (string strTempKeys in l_lstValues)
        {
            bFlag = false;
            sKey = strTempKeys;
            sValue = string.Empty;

            foreach (string strTempValue in strarr)
            {
                if (bFlag)
                {
                    if (strTempValue != sKey && l_lstValues.Contains(strTempValue))
                    {
                        bFlag = false;
                        break;
                    }
                    else
                        sValue += strTempValue;
                }
                else if (strTempValue == sKey)
                    bFlag = true;
            }

            lstResult.Add(new KeyValuePair<string, string>(sKey, sValue));                
        }
0 голосов
/ 09 мая 2011

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

var oStr ="List_1 fooo asdf List_2 bar fdsa XList_3 fooo bar";
        List<String> l_lstValues = new List<string> { "List_1", "List_2", "XList_3" };

        List<string> splitted = new List<string>();
        for(int i = 0; i < l_lstValues.Count; i++)
        {
            var nextIndex = i + 1 >= l_lstValues.Count  ? l_lstValues.Count - 1 : i + 1;
            var length = (nextIndex == i ? oStr.Length : oStr.IndexOf(l_lstValues[nextIndex])) - oStr.IndexOf(l_lstValues[i]);
            var sub = oStr.Substring(oStr.IndexOf(l_lstValues[i]), length);
            splitted.Add(sub);
        }
0 голосов
/ 09 мая 2011

Вы можете использовать метод String.IndexOf , чтобы получить индекс начального символа для каждой фразы в вашем списке.

Затем вы можете использовать этот индекс для разделения строки.

string input = "A foo bar B abc def C opq rst";
List<string> lstValues = new List<string> { "A", "C", "B" };
List<int> indices = new List<int>();

foreach (string s in lstValues)
{
    // find the index of each item
    int idx = input.IndexOf(s);

    // if found, add this index to list
    if (idx >= 0)
       indices.Add(idx);        
}

Как только у вас есть все индексы, отсортируйте их:

indices.Sort();

А затем используйте их для получения результирующих строк:

// obviously, if indices.Length is zero,
// you won't do anything

List<string> results = new List<string>();
if (indices.Count > 0)
{
    // add the length of the string to indices
    // as the "dummy" split position, because we
    // want last split to go till the end
    indices.Add(input.Length + 1);

    // split string between each pair of indices
    for (int i = 0; i < indices.Count-1; i++)
    {
        // get bounding indices
        int idx = indices[i];
        int nextIdx = indices[i+1];

        // split the string
        string partial = input.Substring(idx, nextIdx - idx).Trim();

        // add to results
        results.Add(partial);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...