Trying not to use Regular Expression... lazarus / 21-General ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-17 15:22 Hey Y'all, Let's say I have this string: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  line: String;begin  line:= 'Smileys & Emotion';end; QuoteNote: Yes, I know, the author of the HTML opted for single quotes, not double quotes, the biatch!! So inconsiderate to us Pascal peeps! As the maxim goes: I have an HTML parsing problem and I want to solve it with RegExps... Now you have 2 problems!! So I want to extract the text Smileys & Emotion that sits between the .. tag. How would I go about it without using Regular Expressions? The best I can come up with is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  left, right: Integer;  line, extract: String;begin  line:= 'Smileys & Emotion';  left:= Pos('''>');  Delete(line, 1, left+2); // Deletes the TH  left:= Pos('''>');  Delete(line, 1, left+2); // Deletes the A  right:= Pos('', line);  extract:= Copy(line, 1, right);end; But this is messy and I'm prone to mess up those indexes and counts on both the Delete and Copy. Can anyone suggest a better way than mine but with the caveat that we don't use RegExps? Is there another pattern matching thingamaboob that can manage this, hidden inside an obscure String manipulation unit that I'm unaware of? Many, MANY thanks in advance!! Cheers, Gus ---------------------------------------------------------------------- winni · 2021-09-17 15:40 Hi! very simple  code without error checking: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var p,q : Integer;sl : TStringList;beginsl := TStringList.create;repeatp := pos('<',line);if p  > 0 then  begin  delete(line,1,p);  q := pos ('>',line);  if  q > 0 then sl.add (copy (line,1,q-1));end;until (p=0) or (q=0);ShowMessage (sl.text);sl.free;  Winni ---------------------------------------------------------------------- winni · 2021-09-17 16:15 Hi! Ooops - that was the wrong answer. You want the text between the tags. Here we go: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button3Click(Sender: TObject);var line : String;    sl: TStringList;    p,q,r : integer;begin   line:= 'Smileys & Emotion';   sl := TStringList.create;   repeat   p := pos (' 0 then       begin       delete (line,1,p+1);       q := pos ('>',line);       if q > 0 then         begin         delete (line,1,q);         r := pos ('',line);         if r > 0 then sl.add (copy (line,1,r-1));         end; // q       end; // p         until (p=0) or (q=0);   showMessage (sl.text);   end; Winni ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-17 16:17 Hey Winni, Quote from: winni on September 17, 2021, 05:40:27 pmHi! very simple  code without error checking: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var p,q : Integer;sl : TStringList;beginsl := TStringList.create;repeatp := pos('<',line);if p  > 0 then  begin  delete(line,1,p);  q := pos ('>',line);  if  q > 0 then sl.add (copy (line,1,q-1));end;until (p=0) or (q=0);ShowMessage (sl.text);sl.free;  Winni From just looking at the code, I'm guessing that this will return tr, which is the first tag. I guess I can use a modified approach to eliminate all the tags and be left with only the string I'm looking for. Not a complete solution but it does point me to another solution I haven't thought of. For that alone, MANY thanks Winni!!! Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-17 16:22 Hey Winni, Quote from: winni on September 17, 2021, 06:15:23 pmHi! Ooops - that was the wrong answer. You want the text between the tags. Here we go: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button3Click(Sender: TObject);var line : String;    sl: TStringList;    p,q,r : integer;begin   line:= 'Smileys & Emotion';   sl := TStringList.create;   repeat   p := pos (' 0 then       begin       delete (line,1,p+1);       q := pos ('>',line);       if q > 0 then         begin         delete (line,1,q);         r := pos ('',line);         if r > 0 then sl.add (copy (line,1,r-1));         end; // q       end; // p         until (p=0) or (q=0);   showMessage (sl.text);   end; Winni Yup, this makes a bit more sense, THANKS!!! I'll have a better look at this and generalize it for the other 3 lines I have to parse. And I'll also wait for more people to chime in with some other approach. I like variety Cheers, Gus ---------------------------------------------------------------------- wp · 2021-09-17 16:40 My standard solution in such cases is the fasthtmlparser of FCL. Search the forum, I presented worked-out solutions here several times already. The basic idea is that this parser runs through the text and fires an event OnFoundTag for every tag (part between '<' and '>') and OnFoundText for every text (part between '>' and '<').  Super easy to extract text or table content, but maybe a bit overkill for such a short text phrase as requested here... ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-17 16:57 Hey WP, Quote from: wp on September 17, 2021, 06:40:35 pmMy standard solution in such cases is the fasthtmlparser of FCL. Search the forum, I presented worked-out solutions here several times already. The basic idea is that this parser runs through the text and fires an event OnFoundTag for every tag (part between '<' and '>') and OnFoundText for every text (part between '>' and '<').  Super easy to extract text or table content, but maybe a bit overkill for such a short text phrase as requested here... Ooooooohhhhh, I'm always in the looks for a fine HTML parser lib. I don't think I've stumbled on this one!!! Thanks WP, I'll have a search for your posts!!! And yeah, a bit overkill since one file is ~6MB and the other file is ~33MB. Having events fired for each tag and text, OUCH These are the Emoji lists that I mentioned in another post. I'm trying to extract info from them and I'm gonna put them in a JSON container, maybe... Still need to suss out how I'm gonna include such big datasets in my EmojiMap application. Will need to see how phat is the JSON that I'll extract and if not that big, maybe just add it as a Resource. Nonetheless, many thanks for another approach!! C'mon my fellow Pascalites, keep'em coming Cheers, Gus ---------------------------------------------------------------------- BobDog · 2021-09-17 22:45 A no frills way: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  Type    intArray = Array of int32;  AOS=array of ansistring; // =========  number of partstring in somestring and fill array =============// function tally(somestring:pchar;partstring:pchar;var arr: intarray ):integer;vari,j,ln,lnp,count,num:integer ;filler:boolean;labelskip ,start,return;beginsetlength(arr,0); ln:=len gth(somestring);lnp:=length(partstring);filler:=false;start:count:=0;i :=-1;repeati:=i+1;   if somestring[i] <> partstring[0] then goto skip ;     if somestring[i] = partstring[0] then     begin     for j:=0 to lnp-1 do     begin     if somestring[j+i]<>partstring[j] then goto skip;     end;      count:=count+1;      if filler = true then arr[count]:=i+1 ;      i:=i+lnp-1;     end ;   skip:   until i>=ln-1 ;SetLength(arr,count); // size is now known, repeat the operation to fil arrarr[0]:=count;        // save tally in [0]num:=count;if filler=true then goto return;filler:=true;  goto start;   return:  result:=num;end; procedure getstrings(a:ansistring;chars1:ansistring;chars2:ansistring;var ans:AOS);varf,s:intarray;i,j,count:int32;labellbl;begincount:=0;if (tally(pchar(a),pchar(chars1),f)=0) then exit;if (tally(pchar(a),pchar(chars2),s)=0) then exit;  for i:=1 to f[0]  do  begin for j:=1 to s[0] do begin if ((i>f[0]) or (j>s[0])) then goto lbl; if i=j then   begin   count:=count+1;   setlength(ans,count);   ans[count-1]:= (a[f[i]+length(chars1) .. s[j]-length(chars2)+1]);   end;  end; end; lbl:end;  vara:ansistring;ans:AOS;i:int32; begin a:= 'starters qwerty tree tail end ';a:=a+'  ' ;  getstrings(a,'',ans); for i:=low(ans) to high(ans) do writeln(ans[i]); readln; end. end. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-17 22:50 Hey BobDog, Quote from: BobDog on September 18, 2021, 12:45:52 amA no frills way: WOW, that's a big hunk'a code to digest, LOL!! Let me have some time to have a good look at it Many thanks for the contribution, nonetheless!!! I'm quite grateful that I have so many options to choose from!!! Cheers, Gus ---------------------------------------------------------------------- Jurassic Pork · 2021-09-18 00:32 hello, you can also use the units sax_html, dom_html from fpc. Here is an example to use them ( from a Leledumbo's source code) : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Program ParseHtml;uses  classes,sax_html,dom_html,dom;const  testdata =  '' +  'Smileys & Emotion' +  '';var  doc: thtmldocument;  els: tdomnodelist;  elm: tdomelement;begin  readhtmlfile(doc,tstringstream.create(testdata));  els := doc.GetElementsByTagName('a');  // display first tag found  if els.Count > 0 then writeln(tdomelement(els[0]).textcontent);  readln;end. Friendly, J.P ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-18 01:29 Hey J.P., Quote from: Jurassic Pork on September 18, 2021, 02:32:46 amyou can also use the units sax_html, dom_html from fpc. Many thanks for another HTML parser suggestion!! I'll have a look at this one also!! But for the sizes that I'm looking at: ~6MB and ~33MB, having the whole DOM in mem is a bit too much Nonetheless I welcome another parser to my list. Like I said, I'm always looking for these gems!! Cheers, Gus