2009-04-17 7 views
0

J'essaie de construire une liste qui sera utilisée comme la clause in d'une instruction select. L'exigence est que l'utilisateur entre une liste de descriptions séparées par des virgules. Chaque description peut contenir des espaces, donc je ne peux pas supprimer les espaces avant de diviser par une virgule pour ajouter les guillemets simples autour de chaque description. Je veux supprimer tout l'espace blanc après une seule citation puisque aucune description ne commencera avec un espace. Quelle est la meilleure façon de le faire dans VB.NET? Expression régulière ou une fonction de chaîne? Voici ce que j'ai jusqu'à présent .:Quelle est la meilleure façon de supprimer les espaces après un certain caractère dans une chaîne?

Partial Class Test 
    Inherits System.Web.UI.Page 

    Protected Sub cmdGetParts_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGetParts.Click 
     Dim sDescriptionList As String = "" 
     BuildList(sDescriptionList) 
     RemoveSpacesFromList(sDescriptionList) 
     FillGrid(sDescriptionList) 
    End Sub 

    'Build descriptions List based on txtDescriptionList.Text 
    Private Sub BuildList(ByRef sDescriptionList As String) 
     Dim sDescriptionArray As String() 
     sDescriptionArray = txtDescriptionList.Text.Trim.Split(","c) 
     Dim iStringCount As Integer = 0 
     For Each description In sDescriptionArray 
      If iStringCount > 0 Then 
       sDescriptionList = sDescriptionList & "," 
      End If 
      sDescriptionList = sDescriptionList & "'" & description & "'" 
      iStringCount = iStringCount + 1 
     Next 
    End Sub 

    **'This procedure removes unwanted spaces from description list 
    Private Sub RemoveSpacesFromList(ByRef sList As String) 
     sList = sList.Replace("' ", "'") 
    End Sub** 

    'This procedure fills the grid with data for descriptions passed in 
    Private Sub FillGrid(ByVal sDescriptionList As String) 
     Dim bo As New boPart 
     Dim dtParts As Data.DataTable 
     dtParts = bo.GetPartByDescriptionList(sDescriptionList) 
     GridView1.DataSource = dtParts 
     GridView1.DataBind() 
    End Sub 
End Class 

Modifié: Après avoir examiné ce code, je pense que je peux être en mesure de placer juste description.Trim l'intérieur de la boucle For Each de la procédure construitListe.

+0

En utilisant str = str & élément dans une balance de boucle très mal, comme chaque élément ajouté double l'utilisation de la mémoire. Pour chaque 10 éléments de plus, l'utilisation de la mémoire est environ 1000 fois plus grande. Un StringBuilder est préféré pour construire une chaîne dans une boucle, mais avec ma suggestion ci-dessous vous n'avez pas besoin d'une boucle du tout. – Guffa

Répondre

1

Utilisez une expression régulière pour faire correspondre une virgule avec n'importe quel espace blanc environnant et remplacez par des apostropes et une virgule. L'apostrope de départ pour le premier objet et l'apostrophe de fin pour le dernier objet que vous ajoutez simplement après.

La méthode RemoveSpacesFromList n'est plus nécessaire, car la méthode BuildList fait tout.

Protected Sub cmdGetParts_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGetParts.Click 
    Dim descriptions As String = txtDescriptionList.Text 
    descriptions = BuildList(descriptions) 
    FillGrid(descriptions) 
End Sub 

''//Build descriptions List based on a comma separated string 
Private Function BuildList(ByVal descriptions As String) As String 
    Return "'" + Regex.Replace(descriptions, "\s*,\s*", "','", RegexOptions.Compiled) + "'" 
End Function 

Note:
Si vous utilisez cette chaîne pour construire une requête SQL, votre application est grande ouverte pour des attaques par injection SQL. L'utilisation de requêtes paramétrées est la méthode préférée, mais cela peut ne pas être pratique dans votre cas. L'entrée de l'utilisateur doit au moins être nettoyée avant d'être utilisée dans une requête.

Edit:
Si l'adaptateur utilise l'apostrophe comme caractère d'échappement dans une chaîne littérale, vous pouvez échapper à la chaîne correctement comme ceci:

Private Function BuildList(ByVal descriptions As String) As String 
    Return "'" + Regex.Replace(descriptions.Replace("'","''"), "\s*,\s*", "','", RegexOptions.Compiled) + "'" 
End Function 
+0

Cela réduit vraiment la quantité de code que j'ai besoin d'écrire. Je ne suis pas très familier avec les expressions régulières. Y a-t-il des ressources en ligne que vous recommandez? Je pense qu'il y a un chapitre dans le livre de fondations .NET Applications Development que j'ai. J'ai besoin de relire cette section. Ce qui est recommandé en ce qui concerne la lisibilité et la maintenance des performances et du code; expressions régulières ou fonctions de chaîne? – Jon

+0

J'utilise l'adaptateur de table .xsd dans une couche DAL. L'objet métier appellera la méthode d'extension d'adaptateur de table que j'ai créée et remplacera REPLACE_THIS par la liste de descriptions: select * from table where description in (REPLACE_THIS) Serait-il toujours ouvert aux attaques par injection SQL puisque je ne fais que remplacer Qu'y a-t-il dans la clause IN? – Jon

+0

Les expressions régulières ont tendance à devenir compliquées et donc difficiles à maintenir, mais avec une expression simple comme celle-ci, ce n'est pas un problème. Comparé à votre code d'origine, il a de meilleures performances, mais le code original peut être réécrit à l'aide d'un StringBuilder pour être aussi performant. – Guffa

2

Tant que vous ne pouvez pas avoir intégré des guillemets simples, ce qui suit devrait faire l'affaire

Dim replaced = Regex.Replace(input, "'\s+", "'") 

La chaîne regex '\s+ correspondra à une seule citation suivie par un ou plusieurs caractères blancs. Toutes les instances de ce match seront remplacées par un seul devis.

Questions connexes