Разделение строки во всех пробелах

Мне нужно разбить строку во всех пробелах, она должна ТОЛЬКО содержать сами слова.

Как это сделать в vb.net?

Вкладки, Newlines и т.д. должны быть разделены!

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

Ответ 1

String.Split() (без параметров) разделяет на все пробелы (включая LF/CR)

Ответ 2

Попробуйте следующее:

Regex.Split("your string here", "\s+")

Ответ 3

Если вы хотите избежать регулярных выражений, вы можете сделать это следующим образом:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit"
    .Split()
    .Where(x => x != string.Empty)

Visual Basic эквивалент:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit" _
    .Split() _
    .Where(Function(X$) X <> String.Empty)

Функция Where() важна, поскольку, если ваша строка содержит несколько пробелов рядом друг с другом, она удаляет пустые строки, которые появятся в результате Split().

На момент написания, принятый в настоящее время ответ (fooobar.com/questions/37786/...) не учитывает это.

Ответ 4

String.Split() будет разделяться на каждое одиночное пробелы, поэтому результат будет содержать пустые строки. Решение Regex, предложенное Рубеном Фариасом, является правильным способом сделать это. Я поддержал его ответ, но я хочу дать небольшое дополнение, рассекая регулярное выражение:

\s является класс символов, который соответствует всем пробельным символам.

Чтобы правильно разбить строку, когда она содержит несколько пробельных символов между словами, нам нужно добавить quantifier (или оператор повторения) к спецификации, чтобы соответствовать всем пробелам между словами. В этом случае правильным квантором является +, что означает "одно или несколько" вхождений данной спецификации. Хотя синтаксиса "\s+" здесь достаточно, я предпочитаю более явный "[\s]+".

Ответ 5

Итак, увидев пост Адама Ральфа, я подозревал, что его решение было быстрее, чем решение Regex. Просто подумал, что я поделюсь результатами моего тестирования, так как нашел, что это было быстрее.


В игре действительно действуют два фактора (игнорируя системные переменные): количество выделенных подстрок (определяется количеством разделителей) и общая длина строки. Самый простой сценарий, построенный ниже, использует "A" в качестве подстроки, разделенной двумя пробелами (пробел, за которым следует вкладка). Это подчеркивает влияние количества выделенных подстрок. Я пошел дальше и сделал несколько тестов с несколькими переменными, чтобы получить следующие общие уравнения для моей операционной системы.

Regex()
t = (28,33 * SSL + 572) (SSN/10 ^ 6)

Split(). Где()
t = (6.23 * SSL + 250) (SSN/10 ^ 6)

Где t - время выполнения в миллисекундах, SSL - средняя длина подстроки, а SSN - количество подстрок, разделенных строкой.

Эти уравнения также могут быть записаны как

t = (28.33 * SL + 572 * SSN)/10 ^ 6

и

t = (6.23 * SL + 250 * SSN)/10 ^ 6

где SL - общая длина строки (SL = SSL * SSN)

Вывод: Решение Split(). Where() быстрее, чем Regex(). Основным фактором является количество подстрок, а длина строки играет второстепенную роль. Производительность составляет около 2x и 5x для соответствующих коэффициентов.


введите описание изображения здесь


Здесь мой тестовый код (возможно, более материал, чем необходимо, но он настроен для получения данных с несколькими переменными, о которых я говорил)

using System;
using System.Linq;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace ConsoleApplication1
{
    class Program
    {
        public enum TestMethods {regex, split};
        [STAThread]
        static void Main(string[] args)
        {
            //Compare TestMethod execution times and output result information
            //to the console at runtime and to the clipboard at program finish (so that data is ready to paste into analysis environment)
            #region Config_Variables
            //Choose test method from TestMethods enumerator (regex or split)
            TestMethods TestMethod = TestMethods.split;
            //Configure RepetitionString
            String RepetitionString =  string.Join(" \t", Enumerable.Repeat("A",100));
            //Configure initial and maximum count of string repetitions (final count may not equal max)
            int RepCountInitial = 100;int RepCountMax = 1000 * 100;

            //Step increment to next RepCount (calculated as 20% increase from current value)
            Func<int, int> Step = x => (int)Math.Round(x / 5.0, 0);
            //Execution count used to determine average speed (calculated to adjust down to 1 execution at long execution times)
            Func<double, int> ExecutionCount = x => (int)(1 + Math.Round(500.0 / (x + 1), 0));
            #endregion

            #region NonConfig_Variables
            string s; 
            string Results = "";
            string ResultInfo; 
            double ResultTime = 1;
            #endregion

            for (int RepCount = RepCountInitial; RepCount < RepCountMax; RepCount += Step(RepCount))
            {
                s = string.Join("", Enumerable.Repeat(RepetitionString, RepCount));
                ResultTime = Test(s, ExecutionCount(ResultTime), TestMethod);
                ResultInfo = ResultTime.ToString() + "\t" + RepCount.ToString() + "\t" + ExecutionCount(ResultTime).ToString() + "\t" + TestMethod.ToString();
                Console.WriteLine(ResultInfo); 
                Results += ResultInfo + "\r\n";
            }
            Clipboard.SetText(Results);
        }
        public static double Test(string s, int iMax, TestMethods Method)
        {
            switch (Method)
            {
                case TestMethods.regex:
                    return Math.Round(RegexRunTime(s, iMax),2);
                case TestMethods.split:
                    return Math.Round(SplitRunTime(s, iMax),2);
                default:
                    return -1;
            }
        }
        private static double RegexRunTime(string s, int iMax)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            for (int i = 0; i < iMax; i++)
            {
                System.Collections.Generic.IEnumerable<string> ens = Regex.Split(s, @"\s+");
            }
            sw.Stop();
            return Math.Round(sw.ElapsedMilliseconds / (double)iMax, 2);
        }
        private static double SplitRunTime(string s,int iMax)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            for (int i = 0; i < iMax; i++)
            {
                System.Collections.Generic.IEnumerable<string> ens = s.Split().Where(x => x != string.Empty);
            }
            sw.Stop();
            return Math.Round(sw.ElapsedMilliseconds / (double)iMax, 2);
        }
    }
}

Ответ 6

Я нашел, что использовал решение, как заметил Адам Ральф, плюс комментарий VB.NET ниже на P57, но с одним странным исключением. Я обнаружил, что в конце должен был добавить .ToList.ToArray.

Так же:

.Split().Where(Function(x) x <> String.Empty).ToList.ToArray

Без этого я продолжал получать "Невозможно передать объект типа" WhereArrayIterator`1 [System.String] "для ввода" System.String [] ".

Ответ 7

Dim words As String = "This is a list of words, with: a bit of punctuation" + _
                          vbTab + "and a tab character." + vbNewLine
Dim split As String() = words.Split(New [Char]() {" "c, CChar(vbTab), CChar(vbNewLine) })