Friday, 6 March 2015

regular expression pattern matching in Sharepoint

Linq/regular expression pattern matching  is the best option when we have to get something custom list item as result.
For example : I have a title column in list and title column contains value like
cf-3
cf-3/4-cr
cf-3/4
cf-3/4-sb-30
cf-3 1/2
cf 3
cf 3/4 cr
cf 3/4
cf 3/4 sb 30
cf 3 1/2

   Enter Title :



If user enter cf-3 OR cf 3 and wants a result like in both case i.e. with dash(-) or with space( ).
cf-3,
cf-3/4-cr
cf-3/4
cf-3/4-sb-30
cf-3 1/2
cf 3
cf 3/4 cr
cf 3/4
cf 3/4 sb 30
cf 3 1/2

To achieve this , will use regular expression pattern matching.
First will get contains query for dash search (i.e. cf-3)  and for space search (i.e. cf 3). call SearchDashResult() method for dash search (i.e. cf-3)  and SearchSpaceResult() method for space search (i.e. cf 3).
Case "Title"
                        If (txtTProp4.Text.Trim().IndexOf("-") <> -1) Then
                            wordArrPattern = txtTProp4.Text.Trim().Split("-")
                            SearchDashResult()
                        ElseIf (txtTProp4.Text.Trim().IndexOf(" ") <> -1) Then
                            wordArrPattern = txtTProp4.Text.Trim().Split(" ")
                            SearchSpaceResult()
                        Else
                            strArr.Add("<Contains><FieldRef Name='Title' /><Value Type='Text'>" & txtTProp4.Text.Trim() & "</Value></Contains>")
                        End If

Then , will get contains query for dash search (i.e. cf-3)  and for space search (i.e. cf 3).
Public Sub SearchDashResult()

        If wordArrPattern.Length = 2 Then 'A-B
            beforeSpace = wordArrPattern(0)
            afterSpace = wordArrPattern(1)
            withDash = "-" & afterSpace
            withSpace = " " & afterSpace
            strArr.Add("<Or><And><Contains><FieldRef Name='Title'/><Value Type='Text'>" & beforeSpace & "</Value></Contains><Contains><FieldRef Name='Title'/><Value Type='Text'>" & withDash & "</Value></Contains></And><And><Contains><FieldRef Name='Title'/><Value Type='Text'>" & beforeSpace & "</Value></Contains><Contains><FieldRef Name='Title' /> <Value Type='Text'>" & withSpace & "</Value></Contains></And></Or>")
        End If
End Sub

Public Sub SearchSpaceResult()
        'wordArrPattern = txtTProp2.Text.Trim().Split(" ")
        If wordArrPattern.Length = 2 Then 'A B
            beforeSpace = wordArrPattern(0)
            afterSpace = wordArrPattern(1)
            withDash = "-" & afterSpace
            withSpace = " " & afterSpace
            strArr.Add("<Or><And><Contains><FieldRef Name='Title'/><Value Type='Text'>" & beforeSpace & "</Value></Contains><Contains><FieldRef Name='Title'/><Value Type='Text'>" & withDash & "</Value></Contains></And><And><Contains><FieldRef Name='Title'/><Value Type='Text'>" & beforeSpace & "</Value></Contains><Contains><FieldRef Name='Title' /> <Value Type='Text'>" & withSpace & "</Value></Contains></And></Or>")
        End If
End Sub
Here, we are building caml query.
If strArr.Count <> 0 Then
                entireCAMLQuery = BuildingCAMLUsingStringArr(strArr)
                query.Query = entireCAMLQuery.ToString()
                query.ViewAttributes = "Scope=""Recursive"""
                GetItemThroughtLoop(webSite, strList, query)
                strArr.Clear()
            End If

Private Function BuildingCAMLUsingStringArr(strArr As List(Of String)) As String
        Dim caml As String = String.Empty
        Try
            If strArr.Count = 1 Then
                caml = strArr(0)
            ElseIf strArr.Count > 1 Then
                Dim count As Integer = strArr.Count - 1
                caml = CAMLRecursiveCall(strArr, count)

            End If
        Catch
            Throw
        Finally
        End Try
        Return "<Where>" & caml & "</Where>"
    End Function

    Private Function CAMLRecursiveCall(strArr As List(Of String), count As Integer) As String
        Dim strBuild As New StringBuilder()
        If count > 0 Then
            strBuild.Append("<And>")
            strBuild.Append(CAMLRecursiveCall(strArr, count - 1))
            strBuild.Append(strArr(count))
            strBuild.Append("</And>")
        Else
            strBuild.Append(strArr(count))
        End If
        Return strBuild.ToString()
    End Function

And here , will create linq expression which will give a result which we want
Public Sub GetItemThroughtLoop(webSite As SPWeb, ByVal strList As String, serachQuery As SPQuery)

        Dim site As String = webSite.Url
        Dim List As SPList = webSite.Lists(strList)
        Dim collListItems As SPListItemCollection = List.GetItems(serachQuery)

        Dim txt1val As String = Convert.ToString(txtTProp1.Text.Trim())
        Dim txt2val As String = Convert.ToString(txtTProp2.Text.Trim())
        Dim txt3val As String = Convert.ToString(txtTProp3.Text.Trim())
        Dim txt4val As String = Convert.ToString(txtTProp4.Text.Trim())

        If ((dropListcol1T.Text.Trim() = "Title") OrElse (dropListcol2T.Text.Trim() = "Title") OrElse (dropListcol3T.Text.Trim() = "Title") OrElse (dropListcol4T.Text.Trim() = "Title")) Then
            If (((txt1val.IndexOf("-") <> -1) And (dropListcol1T.Text.Trim() = "Title")) OrElse ((txt2val.IndexOf("-") <> -1) And (dropListcol2T.Text.Trim() = "Title")) OrElse ((txt3val.IndexOf("-") <> -1) And (dropListcol3T.Text.Trim() = "Title")) OrElse ((txt4val.IndexOf("-") <> -1) And (dropListcol4T.Text.Trim() = "Title")) OrElse ((txt1val.IndexOf(" ") <> -1) And (dropListcol1T.Text.Trim() = "Title")) OrElse ((txt2val.IndexOf(" ") <> -1) And (dropListcol2T.Text.Trim() = "Title")) OrElse ((txt3val.IndexOf(" ") <> -1) And (dropListcol3T.Text.Trim() = "Title")) OrElse ((txt4val.IndexOf(" ") <> -1) And (dropListcol4T.Text.Trim() = "Title"))) Then
                getMyPattern = SetResultPatternForTitle()
                strArrPattern = getMyPattern.Split("/")
                sPattern = strArrPattern(0)
                sPattern1 = strArrPattern(1)
            End If
        End If


        If (dropListcol4T.Text.Trim = "Doc Num") Then
            getPatternForDocNum = SetResultPatternForDocNum()
            strArrPattern = getPatternForDocNum.Split("/"' will create new var. for that - it's for just testing
            sPattern = strArrPattern(0)  ' will create new var. for that - it's for just testing
            sPattern1 = strArrPattern(1)   ' will create new var. for that - it's for just testing
        End If



        If collListItems.Count <> 0 Then
            Dim dt As DataTable
            dt = collListItems.GetDataTable()

            Dim source = dt.AsEnumerable()

            If ((dropListcol1T.Text.Trim() = "Title") OrElse (dropListcol2T.Text.Trim() = "Title") OrElse (dropListcol3T.Text.Trim() = "Title") OrElse (dropListcol4T.Text.Trim() = "Title")) Then
                If ((txt1val.IndexOf("-") <> -1) OrElse (txt1val.IndexOf(" ") <> -1)) OrElse ((txt2val.IndexOf("-") <> -1) OrElse (txt2val.IndexOf(" ") <> -1)) OrElse ((txt3val.IndexOf("-") <> -1) OrElse (txt3val.IndexOf(" ") <> -1)) OrElse ((txt4val.IndexOf("-") <> -1) OrElse (txt4val.IndexOf(" ") <> -1)) Then
                    Dim FilterResults = From matchingItem In source Where ((Regex.IsMatch(matchingItem.Field(Of String)("Title"), sPattern, RegexOptions.IgnoreCase)) OrElse (Regex.IsMatch(matchingItem.Field(Of String)("Title"), sPattern1, RegexOptions.IgnoreCase))) Select matchingItem
                    getItemThroughtRowCollection(webSite, strList, FilterResults)
                Else
                    getItemThroughtRowCollection(webSite, strList, source)
                End If
            Else
                getItemThroughtRowCollection(webSite, strList, source)
            End If

        End If

    End Sub

No comments:

Post a Comment