CSDN博客

img mygodsos

字符串处理函数

发表于2008/9/29 14:30:00  343人阅读

 
  1. {************************************
  2. *功能:我的处理字符串的一些类和函数
  3. *说明:SubStrPos---简单字串定位
  4. *      SubStrPosEx---有通配符子串定位
  5. *      SubStrFind---统计子串数量,支持通配符
  6. *      MidSubStr---取中间子串,支持通配符
  7. *版本:1.0
  8. *版权:Big One Tech Co. 2008
  9. *作者:乌龙哈里
  10. *语言:Dephi 2007 for Win32
  11. *初写日期:2008.6.12
  12. *最后修改:2008.6.17
  13. ************************************}
  14. unit MyStr;
  15. interface
  16. uses math;
  17. type
  18.   TStrMsg=record
  19.     Pos,Len:Integer;
  20.   end;
  21.   TStrMsgArray =array of TStrMsg;
  22. //----从S的startpos开始找substr,返回位置。20080617修改
  23. function SubStrPos(const SubStr,S:WideString;const StartPos:Integer=1):Integer;
  24. //----从S的startpos开始找substr,返回strmsg。支持通配符,20080617修改
  25. procedure SubStrPosEx(const SubStr,S:WideString;var SubStrMsg:TStrMsg;const StartPos:Integer=1);
  26. //----查找子串,返回StrMsgArry数组,记录位置和长短,20080617修改
  27. function SubStrFind(const SubStr,S:WideString;var StrMsgArray:TStrMsgArray):Integer;
  28. //----定义左右两边字符,取中间字符内容。支持通配符。20080617修改
  29. function MidSubStr(const LStr,RStr,S:WideString;var StrMsgArray:TStrMsgArray;const ExcludeStr:widestring=''):integer;
  30. type
  31.   THtmlSplit=class
  32.   private
  33.     HtmlText:WideString;
  34.     CellSplit:TStrMsgArray;
  35.     fCount:integer;
  36.     fCellNo:integer;
  37.     function GetfCount:integer;
  38.     function GetfCellNo:integer;
  39.     procedure SetfCellNo(Value:integer);
  40.   public
  41.     procedure Split(const S:widestring;const Symbol:widestring='td');
  42.     function Cell(n:integer):WideString;
  43.     constructor Create; virtual;
  44.     destructor Destroy; override;
  45.     property Count:integer read GetfCount;
  46.     property CellNo:integer read GetfCellNo write SetfCellNo;
  47.   end;
  48. implementation
  49. //===============================================
  50. //*******************HtmlSplit类*****************
  51. //===============================================
  52. constructor THtmlSplit.Create;
  53. begin
  54.   inherited Create;
  55.   fCount:=0;
  56.   fCellNo:=1;
  57. end;
  58. destructor THtmlSplit.Destroy;
  59. begin
  60.   CellSplit:=nil;
  61.   inherited Destroy;
  62. end;
  63. function THtmlSplit.GetfCount:integer;
  64. begin
  65.   Result:=fCount;
  66. end;
  67. function THtmlSplit.GetfCellNo:integer;
  68. begin
  69.   Result:=fCellNo;
  70. end;
  71. procedure THtmlSplit.SetfCellNo(Value:integer);
  72. begin
  73.   if (Value>0and (Value<=fCount) then
  74.     fCellNo:=Value
  75.   else fCellNo:=fCount;
  76. end;
  77. procedure THtmlSplit.Split(const S:widestring;const Symbol:widestring='td');
  78. const
  79.   TdLeft:WideString='<td*>';
  80.   TdRight:WideString='</td>';
  81. var
  82.   LStr,RStr:WideString;
  83. begin
  84.   if Symbol='td' then
  85.   begin
  86.     LStr:='<td*>';
  87.     RStr:='</td>';
  88.   end;
  89.   if Symbol='<>' then
  90.   begin
  91.     LStr:='>';
  92.     RStr:='<';
  93.   end;
  94.   HtmlText:=widestring(S);
  95.   fCount:=MidSubStr(LStr,RStr,HtmlText,CellSplit,'<*>')
  96.  end;
  97. function THtmlSplit.Cell(n:integer):WideString;
  98. begin
  99.   if (n>0and (n<=fCount) then
  100.   begin
  101.     Result:=Copy(HtmlText,CellSplit[n-1].Pos,CellSplit[n-1].Len);
  102.     fCellNo:=n;
  103.   end;
  104. end;
  105. //===============================================
  106. //*******************独立函数********************
  107. //===============================================
  108. //----从S的startpos开始找substr,返回位置。20080613修改
  109. function SubStrPos(const SubStr,S:WideString;const StartPos:Integer=1):Integer;
  110. var
  111.   LenSub,i,j,n:Integer;
  112.   Loop:Boolean;
  113. begin
  114.   Result:=0;
  115.   LenSub:=Length(SubStr);
  116.   i:=StartPos;    //开始位置
  117.   n:=Length(S)-LenSub+1;
  118.   if n>0 then Loop:=True else Loop:=False;
  119.   while (i<=n) and Loop do
  120.   begin
  121.     if S[i]=SubStr[1then
  122.     begin
  123.       j:=1;
  124.       while (j<LenSub) and (S[i+j]=SubStr[j+1]) do Inc(j);   //计算匹配的字数
  125.       if (j=LenSub) then     //完全匹配
  126.       begin
  127.         Loop:=False;
  128.         Result:=i;
  129.       end else inc(i); //不匹配
  130.      end else Inc(i);
  131.   end;
  132. end;
  133. //----从S的startpos开始找substr,返回strmsg。支持通配符,20080617修改
  134. procedure SubStrPosEX(const SubStr,S:WideString;var SubStrMsg:TStrMsg;const StartPos:Integer=1);
  135. const
  136.   Widecard:widechar ='*';  //通配符
  137. var
  138.   i,j,n:integer;
  139.   LenS,LenSub,nPos:integer;
  140.   WidecardSplit:array of WideString;   //被通配符截断的子串
  141.   Loop:Boolean;
  142. begin
  143.   LenS:=Length(S);
  144.   LenSub:=Length(SubStr);
  145.   SetLength(WidecardSplit,LenSub);
  146.   //分析substr
  147.   n:=0;
  148.   if SubStr[1]=Widecard then               //第一个是通配符
  149.   begin
  150.     WidecardSplit[n]:=Widecard;
  151.     inc(n);
  152.   end else WidecardSplit[n]:=WidecardSplit[n]+SubStr[1];  //非通配符全弄成一个
  153.   for i := 2 to LenSub do     //从第二个字符开始,前面已经判断过第一个了
  154.   begin
  155.     if SubStr[i]=Widecard then
  156.     begin
  157.       if SubStr[i-1]<> Widecard then   //连续多个通配符只当一个
  158.       begin
  159.         inc(n);
  160.         WidecardSplit[n]:=Widecard;
  161.         if i<LenSub then inc(n);
  162.       end;
  163.     end else WidecardSplit[n]:=WidecardSplit[n]+SubStr[i];
  164.   end;
  165.   SetLength(WidecardSplit,n+1);         //重新定义widesplit数组的元素个数
  166.   //查找
  167.   j:=StartPos;
  168.   i:=0;
  169.   Loop:=True;
  170.   SubStrMsg.Pos:=0;                //返回找到字符的位置
  171.   SubStrMsg.Len:=0;                //字符的长度
  172.   while (i <= n) and Loop do
  173.   begin
  174.     if WidecardSplit[i]= Widecard then       //如果是通配符
  175.     begin
  176.       if i=0 then SubStrMsg.Pos:=1;          //第一个是通配符定位
  177.       if i=n then SubStrMsg.Len:=LenS+1-SubStrMsg.Pos;  //末尾
  178.       inc(i);
  179.  //     inc(j);
  180.       if i >n then Loop:=False else Loop:=True;
  181.     end else                                 //不是通配符
  182.     begin
  183.       nPos:=SubStrPos(WidecardSplit[i],S,j);
  184.       if nPos>0 then                         //如果找到
  185.       begin
  186.         j:=nPos+Length(WidecardSplit[i]);
  187.         if i=0 then SubStrMsg.Pos:=nPos;    //第一个不是通配符定位
  188.         SubStrMsg.Len:=j-SubStrMsg.Pos;
  189.         Loop:=True;
  190.         inc(i);
  191.       end else
  192.       begin
  193.         Loop:=False;                        //如果没找到
  194.         SubStrMsg.Pos:=0;
  195.       end;
  196.     end;
  197.   end;
  198. end;
  199. //----查找子串,返回StrMsgArry数组,记录位置和长短
  200. function SubStrFind(const SubStr,S:WideString;var StrMsgArray:TStrMsgArray):Integer;
  201. const
  202.   Widecard:widechar='*';
  203. var
  204.   j,n:integer;
  205.   LenS,LenSub:Integer;
  206.   nPos,nStrMsgNum:integer;
  207. //  NoneWide:Boolean;
  208.   strMsg:TStrMsg;
  209. begin
  210.   LenS:=Length(S);
  211.   LenSub:=Length(SubStr);
  212.   SetLength(StrMsgArray,min(10000,LenS));  //1万和整个字串谁小取谁来做数组下标
  213. //处理完毕
  214.   Result:=0;
  215.   nStrMsgNum:=0;
  216.   j:=1;
  217.   //统一写法,好像不慢
  218.   SubStrPosEx(SubStr,S,strMsg,1);
  219.   nPos:=strMsg.Pos;
  220.   while nPos>0 do
  221.   begin
  222.     StrMsgArray[nStrMsgNum].Pos:=strMsg.Pos;
  223.     StrMsgArray[nStrMsgNum].Len:=strMsg.Len;
  224.     Inc(nStrMsgNum);
  225.     j:=nPos+1;
  226.     SubStrPosEx(SubStr,S,strMsg,j);
  227.     nPos:=strMsg.Pos;
  228.   end;
  229.   Result:=nStrMsgNum;
  230.   SetLength(StrMsgArray,nStrMsgNum);  ////---统一写法结束
  231. end;
  232. //----定义左右两边字符,取中间字符内容。支持通配符。20080617修改
  233. function MidSubStr(const LStr,RStr,S:WideString;var StrMsgArray:TStrMsgArray;const ExcludeStr:widestring=''):integer;
  234. var
  235.   i,j,LPos,RPos:integer;
  236.   LenS,nStrMsgNum:integer;
  237.   strMsg:TStrMsg;
  238.   StrMsgArrayB:TStrMsgArray;
  239. begin
  240.   Result:=0;
  241.   LenS:=Length(S);
  242.   j:=1;
  243.   nStrMsgNum:=0;
  244.   SetLength(StrMsgArray,min(10000,LenS));  //1万和整个字串谁小取谁来做数组下标
  245.   SubStrPosEx(LStr,S,strMsg,1);
  246.   while strMsg.Pos>0 do
  247.   begin
  248.     LPos:=strMsg.Pos+strMsg.Len;
  249.     j:=LPos;
  250.     SubStrPosEx(RStr,S,strMsg,j);
  251.     if strMsg.Pos>0 then
  252.     begin
  253.       if ExcludeStr='' then
  254.       begin
  255.         StrMsgArray[nStrMsgNum].Pos:=LPos;
  256.         StrMsgArray[nStrMsgNum].Len:=strMsg.Pos-LPos;
  257.         Inc(nStrMsgNum);
  258.         j:=strMsg.Pos;
  259.         SubStrPosEx(LStr,S,strMsg,j);
  260.       end
  261.       else begin
  262.         RPos:=strMsg.Pos;
  263.         j:=LPos;
  264.         while j<RPos do
  265.         begin
  266.           SubStrPosEx(ExcludeStr,S,strMsg,j);
  267.           if strMsg.Pos>j+1 then
  268.           begin
  269.             StrMsgArray[nStrMsgNum].Pos:=LPos;
  270.             StrMsgArray[nStrMsgNum].Len:=strMsg.Pos-LPos;
  271.             Inc(nStrMsgNum);
  272.           end;    //--if strMsg.Pos>j
  273.           LPos:=strMsg.Pos+strMsg.Len;
  274.           j:=LPos;
  275.           SubStrPosEx(ExcludeStr,S,strMsg,j);
  276.         end;//--while j<RPos
  277.         j:=RPos+1;
  278.         SubStrPosEx(LStr,S,strMsg,j);
  279.       end;//--if ExcludeStr='' else begin
  280.     end;  //-- if strMsg.Pos>0
  281.   end//-- while strMsg.Pos>0
  282.   Result:=nStrMsgNum;
  283.   SetLength(StrMsgArray,nStrMsgNum);
  284. end;
  285. end.
0 0

相关博文

我的热门文章

img
取 消
img