2009-04-17 11 views
0

私は、selectステートメントのin節として使用されるリストを構築しようとしています。ユーザーにコンマ区切りの説明のリストを入力させることが必要です。各説明には空白を含めることができるので、カンマで区切る前にスペースを削除して各説明の周りに一重引用符を追加することはできません。空白で始まる記述がないので、一重引用符の後にすべての空白を削除したい。 VB.NETでこれを行う最善の方法は何ですか?正規表現か文字列関数ですか?ここで私がこれまで持っているものです。:編集文字列内の特定の文字の後に空白を削除するにはどうすればよいですか?

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 

:このコードを確認した後、私は、私はちょうどBuildList手順のFor Eachループ内で description.Trimを配置することができるかもしれないと思います。

+0

列str = strの&アイテムのループのスケールでは非常に悪く、として使用追加される各項目はメモリ使用量を倍増させます。 10個以上のアイテムごとに、メモリ使用量は約1000倍になります。 StringBuilderは文字列をループにするのに適していますが、私の提案ではループは一切必要ありません。 – Guffa

答えて

1

正規表現を使用してカンマを周囲の空白に一致させ、アポストロフィとカンマで置き換えます。最初のアイテムの開始アポストロフィと、最後のアイテムの最後のアポストロフィーは、後で追加するだけです。

RemoveSpacesFromListメソッドは、BuildListメソッドがすべて行うので、もう必要ありません。

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 

注:SQLクエリを構築するために、この文字列を使用している場合
、あなたのアプリケーションは、SQLインジェクション攻撃のために広く開いています。パラメータ化されたクエリを使用するのが望ましい方法ですが、それはあなたの場合には便利ではないかもしれません。ユーザー入力は、少なくとも照会で使用される前に消毒されなければならない。

編集:
アダプタは文字列リテラル内のエスケープ文字としてアポストロフィを使用している場合、あなたはこのように適切に文字列をエスケープすることができます

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

これは本当に私が書く必要があるコードの量を減らします。私は正規表現に慣れていません。あなたが推薦するオンラインリソースはありますか?私は、.NETアプリケーション開発基盤の本には私が持っている章があると思います。私はそのセクションをもう一度読む必要があります。パフォーマンスとコードの可読性/保守性に関しては何が推奨されていますか。正規表現や文字列関数? – Jon

+0

DALレイヤーで.xsdテーブルアダプタを使用しています。ビジネスオブジェクトは、作成したテーブルアダプタ拡張メソッドを呼び出して、説明リストでREPLACE_THISを置き換えます。 select * from table(REPLACE_THIS) これはSQLインジェクション攻撃のために開かれますか? IN句には何が入っていますか? – Jon

+0

正規表現は複雑になる傾向があり、保守が難しいですが、このような単純な表現では問題にはなりません。オリジナルのコードと比べてパフォーマンスは向上しますが、元のコードはStringBuilderを使用して書き直すことができます。 – Guffa

2

限り、あなたは、単一引用符が埋め込まれていることができないよう、トリック

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

に行う必要があり、以下の正規表現文字列'\s+が1つの以上の空白文字が続く任意の単一引用符と一致します。この試合のすべてのインスタンスは一重引用符で置き換えられます。

関連する問題