Как разбить строку на массив строк фиксированной длины?

У меня есть длинная строка, как это

dim LongString as String = "123abc456def789ghi"

И я хочу разбить его на массив строк. Каждый элемент массива должен иметь длину 3 символа.

Например,

Dim LongArray(5) As String
LongArray(0)  = "123"
LongArray(1)  = "abc"
LongArray(2)  = "456"
LongArray(3)  = "def"
LongArray(4)  = "789"
LongArray(5)  = "ghi"

Как мне разделить его с помощью кода VB.net?


person Yoga Fire    schedule 11.09.2011    source источник
comment
Что должно произойти, если длина строки не кратна 3?   -  person Jon Skeet    schedule 11.09.2011
comment
См. msdn.microsoft.com/en-us/ библиотека/6x627e5f(v=vs.80).aspx   -  person BlackJack    schedule 11.09.2011
comment
@Jon Skeet: всегда кратно 3   -  person Yoga Fire    schedule 11.09.2011
comment
@BlackJack: я пробовал. Но каково значение delimiter для моего случая?   -  person Yoga Fire    schedule 11.09.2011
comment
Возможный дубликат stackoverflow.com/questions/1450774/   -  person Paolo Moretti    schedule 11.09.2011
comment
@Yoga Fire: Значит, метод может генерировать исключение, если это не так?   -  person Jon Skeet    schedule 11.09.2011
comment
@Jon Skeet: длина строки будет проверена перед операцией разделения, поэтому нет необходимости в исключении   -  person Yoga Fire    schedule 11.09.2011
comment
@Yoga Fire: лично я предпочел бы проверить аргументы в методе, но вот...   -  person Jon Skeet    schedule 11.09.2011


Ответы (8)


Это может сработать.

 Module Module1

    Sub Main()
        Dim LongString As String = "123abc456def789ghi"
        Dim longlist As New List(Of String)
        For i As Integer = 0 To Convert.ToInt32(LongString.Length / 3) - 1
            longlist.Add(LongString.Substring(i * 3, 3))
        Next
        For Each s As String In longlist
            Console.WriteLine(s)
        Next
        Console.ReadLine()
    End Sub

End Module

И это должно работать в .Net 1.1

Module Module1

    Sub Main()
        Dim LongString As String = "123abc456def789ghi"
        Dim longlist(Convert.ToInt32(LongString.Length / 3) - 1) As String
        For i As Integer = 0 To Convert.ToInt32(LongString.Length / 3) - 1
            longlist(i) = (LongString.Substring(i * 3, 3))
        Next
        For i As Integer = 0 To Convert.ToInt32(LongString.Length / 3) - 1
            Console.WriteLine(longlist(i))
        Next
        Console.ReadLine()
    End Sub

End Module
person chrissie1    schedule 11.09.2011

Вы можете использовать LINQ так:


' VB.NET
Dim str = "123abc456def789ghij"
Dim len = 3
Dim arr = Enumerable.Range(0, str.Length / len).Select (Function(x) str.Substring(x * len, len)).ToArray()


// C#
var str = "123abc456def789ghij";
var len = 3;
var arr = Enumerable.Range(0, str.Length / len).Select (x => str.Substring(x * len, len)).ToArray();

Обратите внимание, что для этого потребуется только полные вхождения длины (т. е. 3 набора в строке длиной 10 символов).

person Aaron    schedule 11.09.2011
comment
Спасибо за ответ, но LINQ не поддерживается для .Net v1.1 - person Yoga Fire; 11.09.2011
comment
@Yoga Возможно, вам следовало написать, что вы все еще используете древние инструменты! - person xanatos; 11.09.2011
comment
@xanatos в его защиту имеет тег .net1.1 к вопросу. - person chrissie1; 11.09.2011
comment
@chrissie1: Только с тех пор, как это добавил xanatos. - person Jon Skeet; 11.09.2011

Этот код С# должен работать:

public static string[] SplitByLength(string text, int length)
{
    // According to your comments these checks aren't necessary, but
    // I think they're good practice...
    if (text == null)
    {
        throw new ArgumentNullException("text");
    }
    if (length <= 0)
    {
        throw new ArgumentOutOfRangeException("length");
    }
    if (text.Length % length != 0)
    {
        throw new ArgumentException
            ("Text length is not a multiple of the split length");
    }
    string[] ret = new string[text.Length / length];
    for (int i = 0; i < ret.Length; i++)
    {
        ret[i] = text.Substring(i * length, length);
    }
    return ret;
}

Reflector преобразует это в VB как:

Public Shared Function SplitByLength(ByVal [text] As String, _
                                      ByVal length As Integer) As String()
    ' Argument validation elided
    Dim strArray As String() = New String(([text].Length \ length)  - 1) {}
    Dim i As Integer
    For i = 0 To ret.Length - 1
        strArray(i) = [text].Substring((i * length), length)
    Next i
    Return strArray
End Function

Возможно, это не идиоматический VB, поэтому я также включил C#.

person Jon Skeet    schedule 11.09.2011
comment
@Jon Почему рефлектор преобразует целочисленное деление в нецелочисленное (VB.NET) деление? Разве он не должен преобразовывать \ в /? Неизвестно условие, что число всегда делится на 3. - person xanatos; 11.09.2011
comment
@Jon Рассказал один из четырех человек с золотым значком VB.NET :-) Это был скорее вопрос, является ли это ошибкой отражателя или что - person xanatos; 11.09.2011

Я разделяю строку на 35.

var tempstore ="12345678901234567890123456789012345";

for (int k = 0; k < tempstore.Length; k += 35) {
    PMSIMTRequest.Append(tempstore.Substring(k,
      tempstore.Length - k > 35 ? 35 : tempstore.Length - k));
    PMSIMTRequest.Append(System.Environment.NewLine);
}

messagebox.Show(PMSIMTRequest.tostring());
person vangli    schedule 15.10.2012

Dim LongString As String = "1234567"

Dim LongArray((LongString.Length + 2) \ 3 - 1) As String

For i As Integer = 0 To LongString.Length - 1 Step 3
    LongArray(i \ 3) = IF (i + 3 < LongString.Length, LongString.Substring(i, 3), LongString.Substring(i, LongString.Length - i))           
Next

For Each s As String In LongArray
    Console.WriteLine(s)
Next

Есть несколько интересных моментов: использование целочисленного деления \ (которое всегда округляется в меньшую сторону), тот факт, что в VB.NET вы должны указать DIM максимальный элемент массива (поэтому длина массива равна +1 ) (это забавно только для программистов на C#) (и это решается с помощью -1 в тусклом), сложение "+ 2" (мне нужно округлить деление на 3 в ВВЕРХ, поэтому я просто добавляю 2 к делимому, я мог бы использовать тернарный оператор и модуль, и в первом тесте я это сделал), и использование тернарного оператора IF() при получении подстроки.

person xanatos    schedule 11.09.2011

Последний массив отсутствует:

Public Function SplitByLength(ByVal text As String, _
                                  ByVal length As Integer) As String()

  ' Argument validation elided
  Dim strArray As String() = New String((text.Length \ length)  - 1) {}
  Dim i As Integer
  For i = 0 To text.Length - 1
      strArray(i) = text.Substring((i * length), length)
  Next i

  ' Get last array:
  ReDim Preserve strArray(i)
  strArray(i) = text.Substring(i * length)
  Return strArray
End Function
person Kan    schedule 30.01.2014

Я добавил еще немного логики в код @jon. Это будет отлично работать для строки, длина которой меньше переданной длины.

 Public Shared Function SplitByLength(ByVal [text] As String, ByVal length As Integer) As String()

    Dim stringLength = text.Length
    Dim arrLength As Integer = ([text].Length \ length) - 1 + IIf(([text].Length 
                                             Mod length) > 0, 1, 0)
    Dim strArray As String() = New String(arrLength) {}

    Dim returnString As String = ""
    Dim i As Integer
    Dim remLength As Integer = 0

    For i = 0 To strArray.Length - 1
      remLength = stringLength - i * length
      If remLength < length Then
        strArray(i) = [text].Substring((i * length), remLength)
      Else
        strArray(i) = [text].Substring((i * length), length)
      End If
    Next i

       Return  strArray
END FUNCTION
person Amir    schedule 05.06.2017

Это мое решение:

Function splitN(str As String, n As Integer) As String()
  For i = 0 To Len(str) Step n + 1
    Try
      str = str.Insert(i + n, "|")
    Catch
    End Try
  Next
  Return str.Split("|")
End Function

Вы можете назвать это так: splitN("abc123def456frg987ef", 3)

person VuongH    schedule 07.07.2020