<p>在编程时,经常会碰到这种情况,我们对一个特定位置出现的子字符串感兴趣,我们需要将它从一大堆字符中提取出来。比如我们可能编写程序来提取一大堆博客网页中的博文,这一大堆博客网页中的博文内容都不相同,但是它们出现的位置是相同的。事实上你可以发现,每个网页,它们的外观是一至的,有着相同的导航条以及侧栏等。通过察看源代码,你会发现,博文内容的前面以及后面,都有着一模一样的HTML代码。而博文内容往往出现在&lt;div id="post-body"&gt;标签以及&lt;/div&gt;&lt;!--博文结束注释--&gt;标签之间。</p>

即形如以下类似的结构:

<div id="post-body">博文内容。博文内容。博文内容。博文内容。</div><!--博文结束注释-->

而我们要做的,正是需要提取上述标签对之间的内容,而上述标签本身以及它们之前与之后的内容,我们都不感兴趣。

对于上面的这种需求,我们可以自己编写一个小函数来满足,就叫它 distillSubString 吧。它接受三个参数,第一个s是母字符串,如一篇博文网页的整个HTML代码;第二个参数sPre是前导字符串模板,如<div id="post-body">;第三个参数sExt是后续字符串模板,如</div><!--博文结束注释-->。它返回位于前导字符串模板与后续字符串模板之间的子字符串。

VB.NET 源码如下:

    ''' <summary>
    ''' 提取子字符串
    ''' </summary>
    ''' <param name="s">母字符串</param>
    ''' <param name="sPre">前导字符串模板</param>
    ''' <param name="sExt">后续字符串模板</param>
    ''' <returns>位于前导字符串模板与后续字符串模板之间的子字符串</returns>
    ''' <remarks>涂鸦,www.myfootprints.cn,2010-4-15</remarks>
    Private Function distillSubString(ByVal s As String, ByVal sPre As String, ByVal sExt As String) As String
        Dim substr As String
    substr = s.Substring(s.IndexOf(sPre) + sPre.Length)
    substr = Microsoft.VisualBasic.Left(substr, substr.IndexOf(sExt))
    distillSubString = substr
End Function

可以这样调用上述函数。

Dim blogContent
Dim parentString = "<div id=""post-body"">博文内容。博文内容。博文内容。博文内容。</div><!--博文结束注释-->"

blogContent = distillSubString(parentString, "<div id=""post-body"">", "</div><!--博文结束注释-->")

以上算法是两步剔除法。对于母字符串的副本,先将前导字符串模板及其以前的所有字符剔除。然后,对于剩下的字符串,将后续字符串模板及其以后的字符全部剔除。

还可以使用这个算法,先找出紧挨着前导字符串模板之后的第一个字符的位置i,这个位置i = 前导字符串模板的开始位置index1加上前导字符串模板的长度;然后再找到后续字符串模板的开始位置index2,并记j = index2 - 1;最后,直接提取母字符串的从第i位置开始到第j位置结束的子字符串。