Hledáni slov v řetězci. – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Hledáni slov v řetězci. – Delphi – Fórum – Programujte.comHledáni slov v řetězci. – Delphi – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Brenyx0
Duch
19. 3. 2016   #1
-
0
-

Zdravím, učím se v Delphi jen chvilku, a právě proto si asi už několikátý den lámu hlavu nad tím, jak z načteného souboru (neco.html), který načítám (zobrazuji)  třeba do Memo nebo RichEditu (raději bych použil Memo), odstraním tagy z HTML kódu, potřebuji v uvedených komponentách zobrazovat jen text bez tagů, s tímto osekaným textem budu dále pracovat.

př:

ref="../html/photos.htm">ZOBRAZOVAT SE BUDE POUZE TOTO</a></li><li><a rel="nofollow" rel="nofollow" rel="nofollow" href="../html/synced_photos.htm">ZOBRAZOVAT SE BUDE POUZE TOTO</a></li><li><a rel="nofollow" rel="nofollow" rel="nofollow" href="../html/videos.htm">ZOBRAZOVAT SE BUDE POUZE TOTO</a></li><li><a rel="nofollow" rel="nofollow" rel="nofollow" href="../html/friends.htm">ZOBRAZOVAT SE BUDE POUZE TOTO</a></li><li><a 

V textu mohou být různé jiné tagy.

Bohužel jsem nikde jinde nenašel způsob, jak se s tímto vypořádat a proto se zde obracím na Vás.

Děkuji za každou radu B.

Nahlásit jako SPAM
IP: 62.209.197.–
JoDiK
~ Anonymní uživatel
987 příspěvků
20. 3. 2016   #2
-
0
-

#1 Brenyx
Takový nástřel:

vyhledej první výskyt < a první výskyt >. Vše co je mezi včetně těch závorek odstraň. To opakuj, dokud se v textu nachází <...

Nahlásit jako SPAM
IP: 88.103.228.–
Brenyx0
Duch
20. 3. 2016   #3
-
0
-

#2 JoDiK

Díky inspiroval jsem se.

Dnes jsem zabředl do řetězců, něco nového jsem se naučil, ale pořád to nestačí.

Zjistil, jsem že soubor (text souboru) načítám po řádcích až do té doby něž jsem na konci souboru, tedy v každém řádku bych měl být schopen najít určitý znak nebo slovo (měl bych hledat po řádcích), zatím umím zjisti kolikátý v pořadí je hledaný znak (nebo začátek slova):

Var
  Radek2: string;
  Soubor2: TextFile;
  cislo:integer;


 begin
  AssignFile(Soubor2,'text.txt');
  while not Eof(Soubor2) do
  begin
  ReadLn(Soubor2, Radek2);
  cislo:=pos('<',Radek2);

  Memo1.lines.Add(Radek2);
  end;
   label1.Caption:=inttostr(cislo);

......

Uvedený zápis vyhodí pozici asi jen posledního nalezeného znaku <, což asi nebude vadit, když bych pak mazal od konce, se znakem > bych to mohl provést stejným způsobem.

Tedy bych zjistil, že poslední pozice uvedených znaků.

A teď to přijde, zde jsem úplně mimo:

Od posledního znaku > bych měl provést mazání až do konce textu  to včetně tohoto znaku - nenašel jsem nikde jakým způsobem (jakým nástrojem) toho docílit.

Pak by mi mělo stačit opět najít poslední > a taky poslední <, tedy bych měl mít zjištěno odkud kam mazat, a takhle bych měl pokračovat až do (začátku textu).

Já vím, že to píšu jak blbec, ale bohužel mi to asi jinak do hlavy nevleze, i za odkaz, kde se podobná problematika řešila, bych byl vděčný.

Jinak díky za reakci B.

Nakonec mě jen napadá, že bych potřeboval, i poradit s tím, jak v textu načteném ze souboru, měnit znak za znak, toto bych použil při opravě diakritiky při načítání html do textového souboru např: Ă=U, Ănor=Únor.

Nahlásit jako SPAM
IP: 62.209.197.–
JoDiK
~ Anonymní uživatel
987 příspěvků
20. 3. 2016   #4
-
+1
-
Zajímavé

#3 Brenyx
U programování neexistuje žádné "asi".

Pos odjakživa hledalo první výskyt - viz např.: zde...

Na mazání od-do z řetězce se už od Pascalu 3.0 používá delete...

Jen asi musíš promyslet a vyřešit to, že v HTML obecně může být < na jednom řádku a odpovídající > klidně až na dalším řádku, nebo i o pět řádků dál...

Nahlásit jako SPAM
IP: 88.103.228.–
Brenyx0
Duch
20. 3. 2016   #5
-
0
-

#4 JoDiK

Děkuji za odkazy, nastuduji, vyzkouším a popřemýšlím.

A ještě díky za trpělivost, nerad otravuji s maličkostmi, i když pro mě je to jak objevit Ameriku.

Až budu mít nějaký kloudný výstup, tak se pochlubím.

Nahlásit jako SPAM
IP: 62.209.197.–
Brenyx0
Duch
21. 3. 2016   #6
-
0
-

#4 JoDiK

Tak sem to spáchal takto:

Var
  Radek: string;
  s:string;
  Soubor: TextFile;
  PrvniZnak:integer;
  PosledniZnak:integer;
  ulozeno:string;
  DelkaRadku:integer;
  Pocatek:integer;
  CetnostZnaku:integer;

begin

      If trim(s) <> '' then
      close;
      AssignFile(Soubor,'text.txt');
      Reset(Soubor);


     while not Eof(Soubor) do
     begin
       ReadLn(Soubor, Radek);
       Delete(Radek,1,1);

       For Pocatek:=0 to 30  do         // - zde je to 30 zadáné ručně
        begin
          PrvniZnak:=pos('>', Radek);
          PosledniZnak:=pos('<', Radek);
          DelkaRadku:=length(Radek)-1;


          If PosledniZnak > PrvniZnak then
            begin
             ulozeno:= Copy(Radek,PrvniZnak+1,PosledniZnak-PrvniZnak-1);
             Delete(Radek,1,PosledniZnak);
             Memo1.Text:=Radek;
             Memo2.Text:=Memo2.Text+ulozeno;
            end;
        end;
       //Label8.Caption:=inttostr(DelkaRadku);              pouze pro kontorlu cyklů
       //label1.Caption:=inttostr(PrvniZnak);
       //label2.Caption:=inttostr(PosledniZnak);
       //label10.Caption:=inttostr(CetnostZnaku);
      end;
end;

Problém je v tom, že jsem nepřišel na to jak zjistit četnost znaku '>' v textu (což je poslední znak), tím bych nastavil počty cyklů.

A další značný problém je v tom, že když budu provádět více jak 50 cyklů, tak už PC zamrzne :), nějaký nápad?

Připojen obrázek.

Nahlásit jako SPAM
IP: 62.209.197.–
JoDiK
~ Anonymní uživatel
987 příspěvků
21. 3. 2016   #7
-
+1
-
Zajímavé

Nenastavuj počet cyklů, použij cyklus s podmínkou...

Dokud se v textu nachází < tak dělej...

while pos('<',radek)>0 do

  begin

    ....

  end;


Každopádně bych asi zkusil spíš použít modernější nástroje nějaký ten pchar nebo jaksetojmenuje, což je délkou neomezený dynamický řetězec, do něj bych to ze souboru naházel a pak v tom jednom řetězci odstraňoval... Tím se vyhneš tomu, že je nějaký HTML příkaz roztažený přes víc řádků...

Nahlásit jako SPAM
IP: 88.103.236.–
mjseven0
Návštěvník
21. 3. 2016   #8
-
+1
-
Zajímavé

Hele jako hraní s řetězci dobrý, ale nebylo by efektivnější přes strejdu Googla pohledat HTML parser  a ty texty si vytahat přes něj? 

Nahlásit jako SPAM
IP: 82.113.32.–
Brenyx0
Duch
21. 3. 2016   #9
-
0
-

#7 JoDiK
Hned na to kouknu, díky B.

Nahlásit jako SPAM
IP: 62.209.197.–
BDS+3
Věrný člen
21. 3. 2016   #10
-
+1
-
Zajímavé

#6 Brenyx
Z delphi si toho už moc nepamatuji, ale věřím, že si tento kód v C# dokážeš do deplhi přepsat

            string input = "><i><color:1256>abcd</color> </i>rs<XX>>tuv<"; //vstupní řetězec
            char[] output = new char[input.Length + 1]; //výpis do pole je lepší, než zvětšovat string

            int p = 0;
            int i = 0; // v delphi se u stringu myslím začíná od indexu 1
            bool searchfornext = false;

            while (i < input.Length) //opakovat dokud neprojdeš všechny znaky (v dephi myslím <=)
            {                
                switch(input[i])
                {
                    case '>': searchfornext = false; break;
                    case '<': searchfornext = true; break;
                    default: if (!searchfornext) { output[p] = input[i]; p++; } break;
                }
                
                i++;
            }

            output[p] = '\0'; //v delphi se budeš muset asi postarat o ukončovací znak

            string str = new string(output); // převod na string

samozřejmě v C# by to šlo napsat lépe (s polovinou řádků), ale schválně jsem to napsal tak, aby to šlo lépe pochopit.

Nahlásit jako SPAM
IP: 185.69.69.–
W10 :)
Řešení
Sniper
~ Anonymní uživatel
215 příspěvků
21. 3. 2016   #11
-
+1
-
Zajímavé
Vyřešeno Nejlepší odpověď

Jasně, dotyčný je zjevně začátečník, tak mu dáme řešení v jiném jazyce, on si to přeloží a upraví  

Pokud jde jenom o to, odstranit tagy, tak já jsem za pět minut spatlal toto (primitivitka která v reálném HTML asi dost narazí): 

Function RemoveTags(const FileName: String): AnsiString;
var
  InputFile:  TFileStream;
  InputText:  AnsiString;
  OutPos:     Integer;
  TagCnt:     Integer;
  i:          Integer;
begin
InputFile := TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite);
try
  SetLength(InputText,InputFile.Size);
  InputFile.Read(PAnsiChar(InputText)^,InputFile.Size);
finally
  InputFile.Free;
end;
SetLength(Result,Length(InputText));
OutPos := 1;
TagCnt := 0;
For i := 1 to Length(InputText) do
  case InputText[i] of
    '<': Inc(TagCnt);
    '>': Dec(TagCnt);
  else
    If TagCnt = 0 then
      begin
        Result[OutPos] := InputText[i];
        Inc(OutPos);
      end;
  end;
SetLength(Result,OutPos - 1);
end;
Nahlásit jako SPAM
IP: 90.179.201.–
Brenyx0
Duch
21. 3. 2016   #12
-
0
-

#11 Sniper
Děkuji všem za řešení mého problému. Hned ráno se na to podívám, i tak si myslím, že to pojedu řádek po řádku a pan google mi bude sekundovat.

Nahlásit jako SPAM
IP: 46.135.6.–
Brenyx0
Duch
23. 3. 2016   #13
-
0
-

#11 Sniper

Vím, že se snažil mi usnadnit práci, ale bohužel i přes to že jsem do toho koukal přes den tak, jsem toho moc nevykoukal, no prostě jsem nepochopil jak to mám zakomponovat, respektive, jak mám uvedenou funkci použít

:(, je to na mě jiný LV.

Nahlásit jako SPAM
IP: 46.135.120.–
Sniper
~ Anonymní uživatel
215 příspěvků
23. 3. 2016   #14
-
+1
-
Zajímavé

Použití je jednoduché, předáš jí html soubor a ona vrátí jeho text bez tagů. Takže třeba:

Memo1.Text := RemoveTags('C:\test\test.htm');
Nahlásit jako SPAM
IP: 90.179.201.–
Brenyx0
Duch
23. 3. 2016   #15
-
0
-

#14 Sniper
Mělo mě to hned napadnout, byl jsem blízko, jen sem si měl pořádně přečíst funkci, děkuji za pomoc, moc mi to pomohlo.

Nahlásit jako SPAM
IP: 62.209.197.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 1 host

Podobná vlákna

Hledání v řetězci — založil vaclav

Hledání v řetězci — založil Dr. ERROR

Hledání textu v řetězci — založil Colpik

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý