关于字符串查找的两个问题(200分)

  • 主题发起人 主题发起人 zxcwuweizxc
  • 开始时间 开始时间
Z

zxcwuweizxc

Unregistered / Unconfirmed
GUEST, unregistred user!
1.在memo1.text中查找<*></*>,*为任意字符,但是要保证两个*值相等。
2.在memo1.text中查找<div和</div>;然后在找到的第一个<div和第一个</div>中查找<div,若找到n个<div,就从第一个</div>后面查找n个</div>。这个程序是判断网页中嵌套层之间关系的,不知道用pos函数行不行。
就这一个问题,把分都送出去了
 
很多分哪。怎么没人回答呢,顶上去
 
用堆栈的方法来判断嵌套,我没有做过,只是记得很多编译器都是这样判断循环语句的嵌套
 
难道用pos函数编不出来???
 
我的个人思路,供你参考下:
用二个表(当然也可以用Strings,strringlist)来保存找到的层,如你所说的<DIV></DIV>
表的结构是这样表1来保存<DIV>,字段如下:字符名<DIV>,层号(找到第五个DIV那么层号就是5),表二的结构也是这样.字符名</diV>,层号(最后一个DIV的层号,如果找到,自动将原DIV的当前层号值减1)oK,结构就这样了
程序段,你做个循环,比如procedure findstr(str :string) ,代码是:
Procedure Findstr(str:string); //str:为传入的一连串字符串,我们在里面找《DIV》
var
sstr:string;
i,ipos,inexpos : integer; //i:来保存层号,第几个DIV;ipos表示当前<div>的位置,inextPos下一个位置
jNext,jpos : integer; //jnext:来保存</div>的层号,对应第几个<DIV>,jPos是几个</DIV>的位置
NoStrings : TStrings; //用来保存<DIV>的队列号
begin
Nostrings := TStringList.create; //用来保存<DIV>的队列号
sstr := str
iPos := pos('<DIV>',sstr);
i:= 0
while iPos>0 do
begin
sstr := copy(sstr,ipos+1,len(sstr)-ipos); //余下字符串
inc(i); //找到的第几个<DIV>
NoStrings.Add(IntTostr(i)); //将当前的第几个<DIV>号保存到队列中
savetable保存记录,将<DIV>,i的值保存到表1中
jpos := pos('</div>',sstr); //找下个</DIV>的位置
inextPos := pos('<DIv>',sstr); //找下个<DIV>的位置
while jpos<inextpos do //第二次循环,找</DIV>,并保存对应的DIV号0
begin
iCount := NoStrings.Count;
JNext := Nostrings[iCount-1]; //最后一个值
NoStrings.Delete[iCount-1]; //删除最后一值;
保存</DIV>,jNext至表2
sStr := copy(sStr,jPos+1,Len(sstr)-jPos); //余下字符串
jpos := pos('</div>',sstr); //找下个</DIV>的位置
inextPos := pos('<DIv>',sstr); //找下个<DIV>的位置
end
iPos := iNextPos; //将下一个<DIV>的位置赋出
end;
end;

思路就是这样,那么执行后,如果你的字符串格式是这样的话:
<DIV><DIV><DIV></DIV></DIV><DIV></DIV></DIV>
那么表一的格式是: 那么表二的格式是:
字符串,层号 字符串,层号
<DIV> 1 </DIV> 3
<DIV> 2 </DIV> 2
<DIV> 3 </DIV> 4
<DIV> 4 </DIV> 1

看你可以以表二来说,就知道,表二的第一条记录</DIV> 3,对应的就是表一的层号为3的记录,那就是表二的第一条对应
表一的第三个DIV ,表示的第三条记录</DIV> 4对应的就是表一的第四个<DIV>,以此类推
代码没经过调试,直接写的,可以参考一下
 
谢谢,那么如果在memo1中查找空标签要怎么编呢,比如<*></*>,*为任意字符,但是要保证两个*值相等,比如<b></b>,或者<h2></h2>。只要前后内容一样就行。
 
把我上面例子的<DIV> </DIV>替换成你的就可以了,你也可以直接当参数来进行传递进来,都是一样的
 
我刚测试了一下,这样做是没问题,你参考下
procedure TForm1.Button1Click(Sender: TObject);
var
sstr:string;
i,ipos,inextpos : integer; //i:来保存层号,第几个DIV;ipos表示当前<div>的位置,inextPos下一个位置
jNext,jpos,icount : integer; //jnext:来保存</div>的层号,对应第几个<DIV>,jPos是几个</DIV>的位置
NoStrings : TStrings; //用来保存<DIV>的队列号
string1,string2 : TStrings;
begin
Nostrings := TStringList.create; //用来保存<DIV>的队列号
string1 := TStringList.Create;
string2 := TStringList.Create;
sstr := memo1.Lines.Text;
iPos := pos('<DIV>',sstr);
i:= 0;
while iPos>0 do
begin
sstr := copy(sstr,ipos+1,length(sstr)-ipos); //余下字符串
inc(i); //找到的第几个<DIV>
NoStrings.Add(IntTostr(i)); //将当前的第几个<DIV>号保存到队列中
string1.Add(inttostr(i)); //保存记录,将<DIV>,i的值保存到表1中
jpos := pos('</DIV>',sstr); //找下个</DIV>的位置
inextPos := pos('<DIV>',sstr); //找下个<DIV>的位置
while (jpos<inextpos) or ((iNextPos=0) and (jPos>0)) do //第二次循环,找</DIV>,并保存对应的DIV号0
begin
iCount := NoStrings.Count;
JNext := strtoint(Nostrings[iCount-1]); //最后一个值
NoStrings.Delete(iCount-1); //删除最后一值;
string2.Add(inttostr(jnext));// 保存</DIV>,jNext至表2
sStr := copy(sStr,jPos+1,Length(sstr)-jPos); //余下字符串
jpos := pos('</DIV>',sstr); //找下个</DIV>的位置
inextPos := pos('<DIV>',sstr); //找下个<DIV>的位置
end;
iPos := iNextPos; //将下一个<DIV>的位置赋出
end;
showmessage(string1.Text);
showmessage(string2.Text);
string1.free;
string2.free;
NoStrings.free;
end;

我在窗体里放了个Memo1
里面的内容是:
<DIV>
asdfasdfasdf
<DIV>
sdfasdfsadfasdfwr<>sdfasf
<DIV>
2wr2refw
</DIV>
</DIV>
<DIV>
w252352
</DIV>
</DIV>
 
谢谢,非常感谢!!!!!
 

Similar threads

回复
0
查看
1K
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
930
SUNSTONE的Delphi笔记
S
后退
顶部