正文

VB应用程序中实现“查找和替换”功能2005-09-25 08:14:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/iamben250/5288.html

分享到:

VB应用程序中实现“查找和替换”功能
                  作者:unknown 更新时间: 2005-05-03  
                  
                        下载本文源代码

                        一、前言

                           尽管Visual
                        Basic并不是我最喜欢的开发工具,但我喜欢它简单而又丰富的库集。每当开发一个需要处理大量文本数据的应用程序时,需要具有拼写错误纠正功能,例如,微软的Word程序,当运行"拼写检查"时,将提供给你一个改正错误的机会(尽管是建议),它同时也提供了"查找替换"工具,用以进行用户定义的单词替换。这篇文章我将解释如何在VB应用程序中实现"查找替换"功能。


                        二、前提条件

                           在解释代码的时候,我假定读者朋友们已经有使用Visual Basic的经验,熟悉Visual
                        Studio开发环境中各种内置的控件及库函数(尽管我使用的不多)。我已经尝试着尽可能地简化程序代码,用不了多久你就可以明白程序的逻辑。如果想对一些库函数(如参数,语法)进一步详细地理解,可以参阅MSDN。图一是程序运行后的效果图:

 

                              图一、程序实现"查找替换"功能时的效果图

                        三、基础工作

                           首先创建一个标准的EXE类型的VB工程,将默认窗体更名为frmMainForm
                        ,在默认窗体上增添一个菜单,具体设置如下(符号"&"用于加速键,单词mnu后的名字用来说明菜单项的名字(在代码中使用)):


                              &Edit
                              ...&Find and Replace mnuFindandreplace
                              E&xit mnuExit

                          
                        向默认窗体添加一个TextBox控件,命名为txtClientArea。使用鼠标调整控件位置和尺寸,使它覆盖窗体的整个客户区,在属性窗口将这个TextBox控件的
                        MultiLine属性设置为"True"。

                           使用Project > Add
                        Form菜单向工程中添加另外一个窗体,将这个窗体命名为"frmFindReplace",并在属性窗口中将它的BorderStyle属性设置为"4
                        -
                        FixedToolWindow"。现在,添加两个TextBox控件,并分别命名为"txtSearchTerm"和"txtReplaceWithString"。添加一个复选框,命名为chkCaseSense。最后,添加一个命令按钮控件,命名为"cmdReplace"。


                           在frmMainForm窗体中添加如下代码:

                              Private Sub mnuExit_Click()
                                End
                              End Sub

                              Private Sub mnuFindandreplace_Click()
                                frmFindReplace.FindnReplace txtClientArea
                              End Sub

                           从上面代码中可以非常明显地看出, 当点击Exit菜单时,我们想终结应用程序,当点击"Find and
                        Replace"菜单时,想通过共用接口frmFindReplace及FindnReplace()方法来激活frmFindReplace窗体。这个公用的接口使查找算法具有普遍性,使用这个接口时,需要提供一个TextBox作为参数(在这里面,搜寻将被执行)。通过使用你自己的TextBox的名字来代替txtClientArea的名字,可以在多个文本框内执行"查找替换"功能,而不用更改代码。"查找和替换"的实现代码主要是在frmFindReplace窗体内,这个模块的代码如下:


                              ' This variable is used for making the algorithm
                              generic.
                              Dim txtClient As TextBox

                              ' This method is the public interface to SnR
                              functionality.

                              Public Sub FindnReplace(ByRef Tb As TextBox)
                                Set txtClient = Tb
                                Me.Show , txtClient.Parent
                              End Sub

                              Private Sub cmdReplace_Click()
                                Dim CaseSense As Integer
                                Dim SourceText As String
                                Dim SourceTextCopy As String
                                Dim Cnt As Integer

                                ' Check for the case sensitivity options
                                If (chkCaseSense.Value = vbChecked) Then
                                 CaseSense = 0
                                Else
                                 CaseSense = 1
                                End If

                                ' One contains the original text and another
                              contains replaced
                                ' (updated) one.
                                ' Used to check whether a replacement was done
                              or not.
                                SourceText = txtClient.Text
                                SourceTextCopy = SourceText

                                If Len(SourceText) = 0 Then
                                 Exit Sub
                                End If

                                On Error GoTo ErrHandler
                                Dim SearchTermLen As Integer
                                Dim FndPos As Integer

                                SearchTermLen = Len(txtSearchTerm.Text)
                                ' Search from the begining of the document.
                                Cnt = 1

                                ' This is endless loop (terminated on a
                              condition checked inside
                                ' the loop body).
                                While (1)

                                FndPos = InStr(Cnt, SourceText,
                              txtSearchTerm.Text, CaseSense)

                                ' When a match is found, replace it
                              appropriately.
                                If (FndPos > 0) Then
                                 SourceText = ReplaceFun(SourceText, FndPos,
                              Len(txtSearchTerm.Text),
                              txtReplaceWithString.Text)
                                 Cnt = FndPos + SearchTermLen
                                Else
                                 Cnt = Cnt + 1
                                End If

                                ' Whether a replacement was done at all or not
                                If (Cnt >= Len(SourceText)) Then
                                 txtClient.Text = SourceText
                                 If (SourceTextCopy <> SourceText) Then
                                  MsgBox "Finished replacing all occurrences.",
                              vbInformation + vbOKOnly, "Replaced All"
                                 Else
                                  MsgBox "No matching strings found. No text
                              replaced.", vbInformation + vbOKOnly, "No
                              Replacement"
                                 End If
                                 Unload Me
                                 Exit Sub
                                End If
                                ' Else Restart from henceforth
                                Wend
                                Exit Sub

                              ErrHandler:
                                Response = MsgBox("An error ocurred while
                              searching. Inform the developer with details.", _
                              vbExclamation + vbOKOnly, "Error Searching")
                              End Sub

                              Private Sub Form_Load()
                                ' Default SearchTerm must be the one selected by
                              the user in
                                ' MainForm
                                If Len(txtClient.SelText) <> 0 Then
                                 txtSearchTerm.Text = txtClient.SelText
                                End If
                              End Sub

                              Function ReplaceFun(Source As String, FromPos As
                              Integer, _
                              Length As Integer, StringTBReplaced _
                              As String) As String
                                ' Replaces a source string with new one
                              appropriately
                                Dim ResultStr As String

                                ResultStr = Left(Source, FromPos - 1)
                                ResultStr = ResultStr & StringTBReplaced
                                ResultStr = ResultStr & Right(Source,
                              Len(Source) - FromPos - Length + 1)

                                ReplaceFun = ResultStr
                              End Function

                              Private Sub txtReplaceWithString_Change()
                                Call EnableDisableReplaceButton
                              End Sub

                              Private Sub txtReplaceWithString_GotFocus()
                                ' Select the contents of the textbox
                                If Len(txtReplaceWithString.Text) <> 0 Then
                                 txtReplaceWithString.SelStart = 0
                                 txtReplaceWithString.SelLength =
                              Len(txtReplaceWithString.Text)
                                End If
                              End Sub

                              Private Sub txtSearchTerm_Change()
                                Call EnableDisableReplaceButton
                              End Sub

                              Private Sub EnableDisableReplaceButton()
                                If Len(txtSearchTerm.Text) <> 0 _
                                 And Len(txtReplaceWithString.Text) <> 0 Then
                                 cmdReplace.Enabled = True
                                Else
                                 cmdReplace.Enabled = False
                                End If
                              End Sub

                              Private Sub txtSearchTerm_GotFocus()
                                ' Select the contents of textbox
                                If Len(txtSearchTerm.Text) <> 0 Then
                                 txtSearchTerm.SelStart = 0
                                 txtSearchTerm.SelLength =
                              Len(txtSearchTerm.Text)
                                End If
                              End Sub

                        四、代码说明

                          
                        公用接口SearchnReplace的"查找替换"算法带有普遍性,使用这种方法,"查找替换"功能可以在任何应用程序中实现,而不用更改frmFindReplace的代码。只是在调用公用接口的地方需要做一些小的改动。


                           "查找和替换"代码在cmdReplace_Click()过程与ReplaceFun()
                        函数下,让我们从cmdReplace_Click()过程开始。

                          
                        首先,变量CaseSense用于跟踪用户的选择,是否是大小写敏感,如果用户选择大小写敏感的话,它的值设置为0,否则,设置为1。变量SourceText和SourceTextCopy用于保存frmMainForm窗体中
                        txtClientArea的内容(或者是用户在主窗体中为TextBox提供的内容,对于本程序来说,它就是txtClientArea),两个变量保存同样的内容将在下面进行解释(一个是临时变量)。变量Cnt用来跟踪文档的结束,当重新从文档开始处进行"查找替换"时它将非常有用。这个变量含蓄地说明了当前光标的位置,下次的"查找替换"将从这个位置开始。


                           主要的算法在while循环内,只要替换或是源TextBox被扫描时,这个循环都将被激活。

                          
                        第二步,我使用了InStr()库函数,它将从第一个参数规定的位置处开始搜索,如果在第二个参数字符串中发现与第三个字符串相匹配的子串,将返回该子串的位置。最后一个参数是大小写敏感选项。


                          
                        InStr()函数的返回值传递给FndPos,如果在源文档中发现了所要查找的字符串,这个值将大于0,否则将返回一个0值。在紧接着的IF语句中,首先替换SourceText变量,然后是通过FndPos
                        + SearchTermLen语句修改Cnt变量,这是必须的,
                        因为下一次的"查找和替换"要从新的位置开始。另一方面,在Else部分,Cnt变量加一,说名查找和替换要从下一个字符开始。紧接着的几个语句用来通知用户查找结果,它们非常容易理解,也非常容易实现。可以直接跳过它们。


                          
                        最后,ReplaceFun()函数进行实际的替换工作,它从源字符串的左边开始,挑选出所有的字符,直到发现所搜索的字符串位置处为止。紧接着,StringTBReplace被添加到结果的后面,它将代替所匹配的源字符串。最后,所有的保留的源字符(排除所要更换的子字符串)被添加到这个结果中去,并作为结果返回。
                        五、结论

                          
                        有很多方法来实现这一功能,但我认为我所使用的方法是最简单也是最直接的,通过例子程序,你可以在应用程序中实现自己的"查找替换"功能。

阅读(1573) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册