Извлечение пары ключ / значение из строки JSON и сохранение специальных символов в значении - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть страница Html с различными массивами JSON. Я использую Agility Pack HTML для захвата innerText со страницы, который изолирует некоторые оставшиеся тексты и массивы JSON на странице (на странице много сложных объектов). Затем я передаю текст в RegEx, как показано ниже, и он анализирует пары ключ / значение; однако это останавливается в апострофе; однако я нуждаюсь в этом и хотел бы сохранить специальные символы для поддержки других функций.

Я получил RegEx от inte rnet, и я уверен, что для настройки специальных символов требуется настройка. Я перепробовал все виды методов; но не будучи экспертом в RegEx, я не могу найти решение. У кого-нибудь есть предложения по исправлению RegeEx?

Dim some_json As String = """{""request"":""Over the last 25 years, I've worked with most of the world’s leading selling strategy systems and built sales training used by companies on six continents. Two years ago, I teamed up with other sales strategy experts to merge our combined experience, wisdom and knowledge into an artificial intelligence system. We worked with expert neuroscientists, behavioral economists, psychologists, and AI programmers to develop JOY, the world’s first emotionally intelligent and sales-savvy artificial intelligence system for sales.  Now I focus on helping companies implement JOY to instantly increase sales and dominate markets.  \n "",""status"":200}"""

        some_json = some_json.Replace("\n", " ")

        Dim r As Regex = New Regex("""(?<Key>[\w]*)"":""?(?<Value>([\s\w\d\.\\\-/:_\+]+(,[,\s\w\d\.\\\-/:_\+]*)?)*)""?")
        Dim mc As MatchCollection = r.Matches(some_json)

        'regex returns summary: Over the last 25 years, I
        'how do I return the entire value with the apostrophe's, special characters?

        For Each k As Match In mc
            Try
                If (k.Groups("Value").Value.Length > 0 And k.Groups("Key").Value = "request") Then
                    m = m & k.Groups("Key").Value & ":" & k.Groups("Value").Value.ToString & "<br/><br/>"
                End If

            Catch ex As Exception
                Dim se As String = ex.Message
            End Try
        Next
        Response.Write(m)

1 Ответ

0 голосов
/ 07 февраля 2020

Решил, выбросив RegEx, и использовал рекурсивную функцию, чтобы вытянуть что-нибудь с любой глубины json. Он выводит пары имя / значение. Если есть глубокий объект, он складывает имена ключей (например, глубину4.depth3.depth2) и затем следует со значением. Так что простая строка сравнивает ключ (комбинированный), и вы можете извлечь значение.

Private Shared Function ParseJson(ByVal token As JToken, ByVal nodes As Dictionary(Of String, String), ByVal Optional parentLocation As String = "") As Boolean
    If token.HasValues Then

        For Each child As JToken In token.Children()

            If token.Type = JTokenType.[Property] Then

                If parentLocation = "" Then
                    parentLocation = (CType(token, JProperty)).Name
                Else
                    parentLocation += "." & (CType(token, JProperty)).Name
                End If
            End If

            ParseJson(child, nodes, parentLocation)
        Next

        Return True
    Else

        If nodes.ContainsKey(parentLocation) Then
            nodes(parentLocation) += "|" & token.ToString()
        Else
            nodes.Add(parentLocation, token.ToString())
        End If

        Return False
    End If
End Function

Использование:

Private Sub Test_Load(sender As Object, e As EventArgs) Handles Me.Load

    Dim ServerPath As String = HttpRuntime.AppDomainAppPath
    Dim left_overs As String = String.Empty

    'download web page
    Dim html = New HtmlDocument()
    html.LoadHtml(New WebClient().DownloadString(ServerPath & "files/somefile.htm"))

    Dim txt As String = html.DocumentNode.InnerText, m As String = String.Empty

    Try
        Dim ndes As Array = html.DocumentNode.SelectNodes("//cde").ToArray
        For Each item As HtmlNode In ndes

            Dim s As String = item.InnerText.Trim
            'Response.Write(s)
            Try

                Dim nodes As Dictionary(Of String, String) = New Dictionary(Of String, String)()
                Dim rootObject As JObject = JObject.Parse(s)
                ParseJson(rootObject, nodes)

                For Each key As String In nodes.Keys
                    If key = "included.summary" Then

                        left_overs = AlphaNumericOnly(nodes(key))
                        m = m & key & " = " & left_overs & "<br/><br/>"
                        Response.Write(m)
                    End If
                Next

            Catch ex As Exception
                Dim err As String = ex.Message
            End Try

        Next
    Catch ex As Exception
    End Try

End Sub

И немного функции очистки.

Public Shared Function AlphaNumericOnly(strSource As String) As String
    Dim i As Integer
    Dim strResult As String = String.Empty

    For i = 1 To Len(strSource)
        Select Case Asc(Mid(strSource, i, 1))
            Case 32 To 91, 93 To 126 'include 32 if you want to include space
                strResult = strResult & Mid(strSource, i, 1)
        End Select
    Next
    AlphaNumericOnly = strResult
End Function
...