【问题标题】:What's the best way to remove white space after a certain character in a string?在字符串中某个字符之后删除空格的最佳方法是什么?
【发布时间】:2009-04-17 14:24:43
【问题描述】:

我正在尝试构建一个列表,该列表将用作 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 

已编辑:查看此代码后,我想我可以将 description.Trim 在 BuildList 过程的 For Each 循环内。

【问题讨论】:

  • 在循环中使用 str = str & item 的扩展性非常差,因为每个添加的项目都会使内存使用量翻倍。每增加 10 个项目,内存使用量就会增加大约 1000 倍。 StringBuilder 是在循环中构建字符串的首选,但根据我的建议,您根本不需要循环。

标签: vb.net string


【解决方案1】:

只要你不能嵌入单引号,下面应该可以解决问题

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

正则表达式字符串'\s+ 将匹配任何后跟一个或多个空白字符的单引号。此匹配的所有实例都将替换为单引号。

【讨论】:

    【解决方案2】:

    使用正则表达式将逗号与任何周围的空格匹配,并用撇号和逗号替换。第一个项目的起始撇号和最后一个项目的结束撇号,您只需在之后添加。

    不再需要 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
    

    【讨论】:

    • 这确实减少了我需要编写的代码量。我对正则表达式不是很熟悉。有没有推荐的在线资源。我认为我的 .NET 应用程序开发基础书中有一章。我需要重新阅读该部分。就性能和代码可读性/维护而言,推荐什么;正则表达式还是字符串函数?
    • 我在 DAL 层中使用 .xsd 表适配器。业务对象将调用我创建的表适配器扩展方法并将 REPLACE_THIS 替换为描述列表: select * from table where description in (REPLACE_THIS) 这是否仍可用于 SQL 注入攻击,因为我只是替换 IN 中的内容子句?
    • 正则表达式往往会变得复杂,因此难以维护,但是像这样简单的表达式不会有问题。与您的原始代码相比,这具有更好的性能,但可以使用 StringBuilder 重写原始代码以达到同样出色的性能。
    • 无论您使用什么字符串方法来组合查询,替换都不能保护查询。
    猜你喜欢
    • 2011-10-03
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多