将SQL片段字符串解析为Listbox控件的List(字符串)的最佳方法是什么?

时间:2017-05-10 14:39:36

标签: asp.net .net vb.net

我正在尝试使用此字符串:

(("DISPLAY_NAME" like N'sadf%') And ("ID" = 2) And ("IsCRITERION" = null))

并将其解析为List(字符串),以便它可以显示为:

(
    (
        "DISPLAY_NAME" like N'sadf%'
    ) 
    And 
    (
        "ID" = 2
    ) 
    Or 
    (
        "IsCRITERION" = null
    )
)

我很接近但却没有。我的代码目前看起来像:

Dim filterlist As New List(Of String)
Dim temp As String = String.Empty
Dim lvl As Integer = 0
Dim pad As String = String.Empty
For Each chr As Char In originalString  '--- filter is the string i posted above
    Select Case chr.ToString.ToLower()
        Case "("
            filterlist.Add(pad.PadLeft(lvl * 5) & chr)
            lvl += 1
        Case ")"
            filterlist.Add(pad.PadLeft(lvl * 5) & temp)
            If lvl > 0 Then lvl -= 1
            filterlist.Add(pad.PadLeft(lvl * 5) & chr)
            'If lvl > 0 Then lvl -= 1
            temp = String.Empty
        Case Else
            temp &= chr
    End Select
Next

'--- Removes the empty line produced by generating the List(of String)
filterlist = filterlist.Where(Function(s) Not String.IsNullOrWhiteSpace(s)).ToList()

listSelectedCriteria.DataSource = filterlist
listSelectedCriteria.DataBind()

不幸的是,上面的代码产生了一些接近我想要的东西但是“And”和“Or”不在正确的位置:

(
    (
        "DISPLAY_NAME" like N'sadf%'
    ) 
    (
        And "ID" = 2
    )  
    (
        Or "IsCRITERION" = null
    )
)

使用正则表达式会更好吗?谢谢你的帮助

2 个答案:

答案 0 :(得分:2)

可能“最好”的方式(尽管进入“主要基于意见的”领域)将是使用解析器,但假设您的输入仅限于类似的字符串,这就是我想出的:

Dim originalString = "((""DISPLAY_NAME"" like N'sadf%') And (""ID"" = 2) And (""IsCRITERION"" = null))"
Dim filterlist = New List(Of String)()
Dim temp = New StringBuilder()
Dim lvl = 0
Dim addLine =
    Sub(x As String)
        filterlist.Add(New String(" ", lvl * 4) & x.Trim())
    End Sub
For Each c In originalString
    Select Case c
        Case "("
            If temp.Length > 0 Then
                addLine(temp.ToString())
                temp.Clear()
            End If
            addLine("(")
            lvl += 1
        Case ")"
            If temp.Length > 0 Then
                addLine(temp.ToString())
                temp.Clear()
            End If
            lvl -= 1
            addLine(")")
        Case Else
            temp.Append(c)
    End Select
Next
If temp.Length > 0 Then
    addLine(temp.ToString())
    temp.Clear()
End If

filterlist.Dump() ' LINQPad ONLY

这导致:

( 
    ( 
        "DISPLAY_NAME" like N'sadf%' 
    ) 
    And 
    ( 
        "ID" = 2 
    ) 
    And 
    ( 
        "IsCRITERION" = null 
    ) 
) 

但是,您可能最终不得不添加代码,因为您发现不同的输入并不能达到您想要的效果。

答案 1 :(得分:0)

我不会看每个角色,而是开始分裂。然后根据开头的字符添加/删除填充。

    Dim tempString As String = "((""DISPLAY_NAME"" like N'sadf%') And (""ID"" = 2) And (""IsCRITERION"" = null))"
    Dim curPadding As String = ""
    Const padding As String = "    "
    Dim result As New List(Of String)

    For Each s As String In Text.RegularExpressions.Regex.Split(tempString, "(?=[\(\)])")
        If s <> "" Then
            If s.StartsWith("(") Then
                result.Add(curPadding & "(")
                curPadding &= padding
                result.Add(curPadding & s.Substring(1).Trim())
            ElseIf s.StartsWith(")") Then
                curPadding = curPadding.Substring(padding.Length)
                result.Add(curPadding & ")")
                result.Add(curPadding & s.Substring(1).Trim())
            Else
                result.Add(curPadding & s)
            End If
        End If
    Next
相关问题