正则表达式分裂字符串在特定的单词模式不同的不同值

时间:2013-08-08 10:05:51

标签: asp.net regex vb.net oracle

我正在做动态报告系统。对于前端我使用Asp.net和oracle作为后端。项目要求是,用户可以在TextBox中编写查询,并在点击 WHERE 关键字后的查询按钮时将所有参数拆分。拆分将根据模式工作,在查询中找到( AND | OR | )。

例如: -

select * from EmpInfo where age >= 40, active='A' and rownum < 15

结果将

age >= 40
active='A'
rownum < 15

但是,如果我在之后使用子查询,那么也将遵循相同的模式

例如: -

select * from EmpInfo where age in (select age from Emp_pns where age >= 60 ), active='A' and rownum < 15

结果将

age >= 60
active='A'
rownum < 15

这是我的示例代码,我尽我所能,但我没有得到完美的解决方案。

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim query As String = TextBox1.Text.ToLower
getParameter(query)
For i As Integer = 0 To ListBox2.Items.Count - 1
    ListBox1.Items.Add(ListBox2.Items(i).Text)
Next
End Sub

Public Sub getParameter(ByVal argument As String)
Dim query As String = argument
Static Dim tempString As String
If query.Contains("order by") Or query.Contains("group by") Then
    Dim mtch As Match = Regex.Match(query, "(?<=where)(.*)(?=order by|group by)")
    Dim mtchString As String = mtch.Groups(1).Value
    tempString = mtchString
    If mtchString.Length >= 1 Then
        Dim bindlist As String() = Regex.Split(mtchString, " and | or |,")
        ListBox1.DataSource = bindlist
        ListBox1.DataBind()
         getParameter(tempString)
    End If
Else
    Dim mtch As Match = Regex.Match(query, "(?<=where)(.*)")
    Dim mtchString As String = mtch.Groups(1).Value
    Dim bindlist As String() = Regex.Split(s, " and | or |,")
    ListBox2.DataSource = bindlist
    ListBox2.DataBind()
End If

End Sub

1 个答案:

答案 0 :(得分:1)

RegexSplit可为明确定义的模式提供准确的效果;您正在寻找的模式对于那些方法而言过于复杂(所需的实现将太困难,并且在任何情况下都太严格)。这种复杂的问题应该依靠字符串分析来解决。使用输入字符串(或等效字符串)提供预期结果的示例代码:

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim inputString As String = "select * from EmpInfo where age in (select age from Emp_pns where age >= 60 ), active='A' and rownum < 15"

        Dim whereString As String = inputString.Substring(inputString.ToLower().IndexOf("where") + "where".Length, inputString.Length - (inputString.ToLower().IndexOf("where") + "where".Length)).Trim()
        Dim allParts(whereString.Length + 2) As String
        Dim allPartsCount As Integer = 0
        Dim done As Boolean = False
        If (whereString.Contains("(") And whereString.Contains(")")) Then
            If (whereString.Split("(").Length = whereString.Split(")").Length) Then
                done = True
                Dim remString = whereString
                Do
                    Dim temp = inBrackets(remString)
                    If (temp(0).Trim().Length > 0) Then
                        allPartsCount = allPartsCount + 1
                        allParts(allPartsCount) = temp(0)
                    End If
                    If (temp(1).Trim().Length > 0) Then
                        remString = temp(1)

                    Else
                        Exit Do
                    End If
                Loop While (remString.Trim().Length > 0)
            End If
        End If
        If (Not done) Then
            'Standard treatment
        End If

    End Sub

    Private Function inBrackets(inputString As String) As String()

        Dim outStrings(1) As String

        Dim openBracket As Boolean = False
        Dim count As Integer = -1
        Do
            count = count + 1
            outStrings(0) = outStrings(0) & inputString.Substring(count, 1)
            If (inputString.Substring(count, 1) = "(") Then
                openBracket = Not openBracket
            ElseIf (openBracket And inputString.Substring(count, 1) = ")") Then
                openBracket = False
            End If

            If (Not openBracket) Then
                If (inputString.Substring(count, 1) = ",") Then
                    Exit Do
                ElseIf (count >= "and".Length AndAlso inputString.ToLower().Substring(count - "and".Length, "and".Length) = "and") Then
                    Exit Do
                ElseIf (count >= "or".Length AndAlso inputString.ToLower().Substring(count - "or".Length, "or".Length) = "or") Then
                    Exit Do
                End If
            End If
        Loop While (count < inputString.Length - 1)

        If (outStrings(0).Trim().Length > 0) Then
            outStrings(1) = inputString.Substring(outStrings(0).Length, inputString.Length - outStrings(0).Length)
        End If

        Return outStrings

    End Function
End Class

此代码显示了针对此类情况的典型方法:您需要根据需要调整/扩展它以满足您的确切要求。它分析了只有支架的情况(平行数量的开/关括号)。这个想法很简单:逐个字符地分析给定的字符串,直到找到你正在寻找的“分隔符”之一,并另外考虑一下:如果找到一个开括号,它将不会退出循环直到找到相应的结束一。执行分析的函数返回一个包含当前位和剩余字符串的数组,以便主循环可以继续分析。在任何情况下你都应该进行进一步的扩展:括号变化(例如方括号),占嵌套括号(此代码只占“括号的一个级别”)等等。