【问题标题】:Regex Split String at particular word pattern different different value特定单词模式的正则表达式拆分字符串不同的不同值
【发布时间】:2013-08-09 23:59:24
【问题描述】:

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

例如:-

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

结果会

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

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

例如:-

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

【问题讨论】:

  • 请看一下我的代码,了解处理括号的内在复杂性。您不能依靠具有如此复杂现实的拆分/正则表达式;或者生成的模式会非常复杂/不灵活,以至于不值得。建议的方法为您的情况甚至更复杂的情况提供了完美的解决方案。我希望你没有误解我的陈述,无论如何我现在会更新我的答案。

标签: asp.net regex vb.net oracle


【解决方案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

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

【讨论】:

  • 为什么这两个不同:(..."this is me".split(/\s/); vs "this is me".split(/(\s)/);
  • @MuhammadUmer 这不是拆分应该使用的方式;还要记住,特殊字符必须转义。无论如何,我认为这与您的原始问题没有任何关系,因此您应该发布一个新问题。如果这是一个或多或少长/复杂的问题,您应该发布一个新问题。如果这只是一个简单的问题,我可以为您解答(上次,因为如前所述,事情不应该这样做):解释确切的输入字符串以及您希望如何拆分它。跨度>
  • @MuhammadUmer ?!你不是OP?!你为什么要问一个与这里的问题和我的答案无关的问题?!​​
  • 不,我只是想了解为什么它的行为不同。我问是因为你似乎知道。
  • @MuhammadUmer 我确实知道 split 的行为以及如何处理字符串,而您在这两件事上都做错了。请解释一下你想要什么,我会写一个合适的代码;您写的是无意义的:此代码无法编译(您必须用“”或“”包围拆分字符,具体取决于是字符还是字符串),您必须包含拆分字符存在于要拆分的字符串中(这里不是这种情况);如果您有特殊字符,则必须对它们进行转义(这是处理字符串/字符时普遍有效的规则)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 2021-09-27
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多