Как преобразовать строку в список? - PullRequest
1 голос
/ 23 февраля 2020

Как я могу RegEx эту строку в список?

Моя строка выглядит так:

google (2.0.3)                         - Python bindings to the Google search engine.
bits-google (1.12.17)                  - BITS Google
oauthkit-google (0.1.2)                - OAuthKit for Google
google-reauth (0.1.0)                  - Google Reauth Library
google-common (0.0.1)                  - Google namespace package
google-colab (1.0.0)                   - Google Colaboratory tools
google-auth (1.11.2)                   - Google Authentication Library
  INSTALLED: 1.7.0
  LATEST:    1.11.2
google-endpoints (4.8.0)               - Google Cloud Endpoints
google-oauth (1.0.1)                   - OAuth2 for Google APIs
google-gax (0.16.0)                    - Google API Extensions
google-finance (0.1.0)                 - Google Finance API ikmgitj oijhotrjtrhj
                                         kjhghjihotrhjtri9h

Я хочу получить name, version, description, и, в конце концов, если он установлен.

Я знаю, как разделить строку только одним пробелом, но как мне это сделать, если строка имеет несколько пробелов, которые меняются и имеют значение Да sh в это?

РЕДАКТИРОВАТЬ:

Я интегрировал код сейчас, как это (Для людей, которые заинтересованы. Кредит ):

 Dim patt = "(.*?.)(\(\d+.\d+.\d+\)|\d+.\d+.\d+)(=?.*?-.)?(.*)"
        Dim matches = Regex.Matches(sOutput, patt, RegexOptions.IgnoreCase)
        Dim found_packages As New Dictionary(Of String, List(Of String))

        For Each m As Match In matches
            Dim key = m.Groups(1).Value.Trim({" "c, ":"c})
            If key = "INSTALLED" Then
                found_packages(found_packages.Last().Key).Add(m.Groups(2).Value.Trim({" "c, ":"c}))
                Continue For
            ElseIf key = "LATEST" Then
                Continue For
            End If

            found_packages.Add(key, New List(Of String))
            found_packages(key).Add(m.Groups(2).Value.Trim({" "c, ":"c}).Replace("(", "").Replace(")", ""))
            If Not String.IsNullOrWhiteSpace(m.Groups(4).Value) Then
                found_packages(key).Add(m.Groups(4).Value.Trim({" "c, ":"c}))
            End If
        Next

        For Each package In found_packages
            Dim item As New ListViewItem
            item.Text = package.Key
            item.SubItems.Add(package.Value(0))
            item.SubItems.Add(package.Value(1))
            If package.Value.Count > 2 Then
                item.SubItems.Add(package.Value(2))
            End If


            lvPackages.Items.Add(item)
        Next

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Вы можете использовать RegEx для анализа этих входных данных и создания Dictionary(Of String, List(Of String)), где каждая запись значения ключа является свойством (name) с несколькими значениями (version и description):

Dim patt = "(.*?.)(\(\d+.\d+.\d+\)|\d+.\d+.\d+)(=?.*?-.)?(.*)"
Dim matches = Regex.Matches(txtIn.Text, patt)
Dim dict As New Dictionary(Of String, List(Of String))

For Each m As Match In matches
    Dim key = m.Groups(1).Value.Trim({" "c, ":"c})

    dict.Add(key, New List(Of String))
    dict(key).Add(m.Groups(2).Value.Trim({" "c, ":"c}))
    If Not String.IsNullOrWhiteSpace(m.Groups(4).Value) Then
        dict(key).Add(m.Groups(4).Value.Trim({" "c, ":"c}))
    End If
Next

dict содержит следующее:

google
     (2.0.3)
     Python bindings to the Google search engine.
bits-google
     (1.12.17)
     BITS Google
oauthkit-google
     (0.1.2)
     OAuthKit for Google
google-reauth
     (0.1.0)
     Google Reauth Library
google-common
     (0.0.1)
     Google namespace package
google-colab
     (1.0.0)
     Google Colaboratory tools
google-auth
     (1.11.2)
     Google Authentication Library
INSTALLED
     1.7.0
LATEST
     1.11.2
google-endpoints
     (4.8.0)
     Google Cloud Endpoints
google-oauth
     (1.0.1)
     OAuth2 for Google APIs
google-gax
     (0.16.0)
     Google API Extensions
google-finance
     (0.1.0)
     Google Finance API ikmgitj oijhotrjtrhj kjhghjihotrhjtri9h

Вы можете получить значения (version и description) клавиши google (name) например, следующим образом:

Dim version = dict("google")(0)
Dim descrip = dict("google")(1)

Обратите внимание, что клавиши INSTALLED и LATEST не имеют значения description, поэтому Dim descrip = dict("LATEST")(1) вызовет исключение. Поэтому вы должны проверить в первую очередь. Теперь у вас есть словарь dict, где dict.Keys - это name-s, а dict.Values - version-s и description-s для каждой клавиши.

Если вы просто хотите создать List(Of String):

Dim patt = "(.*?.)(\(\d+.\d+.\d+\)|\d+.\d+.\d+)(=?.*?-.)?(.*)"
Dim matches = Regex.Matches(txtIn.Text, patt)
Dim lst As New List(Of String)

For Each m As Match In matches
    lst.Add(m.Groups(1).Value.Trim({" "c, ":"c}))
    lst.Add(m.Groups(2).Value.Trim({" "c, ":"c}))
    If Not String.IsNullOrWhiteSpace(m.Groups(4).Value) Then
        lst.Add(m.Groups(4).Value.Trim({" "c, ":"c}))
    End If
Next

Вот тест regex101 для предыдущего шаблона RegEx.


Редактировать: Предлагаемые улучшения

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

  • Вы можете избавиться от Dictionary(Of String, List(Of String)) и работать непосредственно с ListViewItemCollection элемента управления ListView. Таким образом, только один ForEach l oop сделает работу.
Dim patt = "(.*?.)(\(\d+.\d+.\d+\)|\d+.\d+.\d+)(=?.*?-.)?(.*)"
Dim matches = Regex.Matches(sOutput.Text, patt)

lvPackages.BeginUpdate()
lvPackages.Items.Clear()

For Each m As Match In matches
    Dim key = m.Groups(1).Value.Trim({" "c, ":"c})

    If key.IndexOf("latest", StringComparison.InvariantCultureIgnoreCase) >= 0 Then
        Continue For
    End If

    Dim lvi As ListViewItem

    If key.IndexOf("installed", StringComparison.InvariantCultureIgnoreCase) >= 0 Then
        lvi = lvPackages.Items.OfType(Of ListViewItem).LastOrDefault
        'Just in case
        If lvi IsNot Nothing Then
            lvi.SubItems.Add(m.Groups(2).Value.Trim({" "c, ":"c}))
        End If
        Continue For
    End If

    lvi = New ListViewItem(key)

    'Add the version..
    lvi.SubItems.Add(Regex.Match(m.Groups(2).Value, "\d+.\d+.\d+").Value)

    If Not String.IsNullOrWhiteSpace(m.Groups(4).Value) Then
        'Add the description..
        lvi.SubItems.Add(m.Groups(4).Value.Trim({" "c, ":"c}))
    End If

    lvPackages.Items.Add(lvi)
Next

'Optional: Auto size each column to fit the longest item.
lvPackages.Columns.Cast(Of ColumnHeader).
    ToList().ForEach(Sub(x) x.Width = -1)

lvPackages.EndUpdate()

Проверьте это.

1 голос
/ 23 февраля 2020

Это работа для регулярных выражений. Вы можете проанализировать строку, используя переменное количество пробельных символов. Я не уверен насчет vb, но в python я бы сделал что-то вроде этого (но итерируя по каждой строке, разбивая на основе \ r):

python regex

...