Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Anfängerfragen zum Programmieren mit PureBasic.
proggernewbie
Beiträge: 19
Registriert: 23.03.2017 11:05
Computerausstattung: Win7 64bit, PureBasic 5.61 64bit
Linux Mint 19.1 64bit, PureBasic 5.71 64bit
VM (WinXP 32bit, PureBasic 5.71)
Wohnort: Kreis RE

Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von proggernewbie »

Hallo zusammen,
ich bin inzwischen fast 58 Jahre und habe es imme rnoch nicht aufgegeben Programme erstellen zu wollen. Meinen PB-Compiler habe ich sicherlich schon seit etwa 10 Jahren immer wieder installiert und erste Gehversuche gemacht, aber leider bin ich nie darüber hinaus gekommen.
Aus aktuellem Anlass, möchte ich gerne Textdateien bearbeiten. Dazu habe ich mir z.B. von der Webseite Anne Will die Kommentare als Einzeldateien herunter geladen. Das habe ich mit Codefragmenten noch selbst geschafft, die ich im Forum gefunden bzw. selbst erarbeitet habe.

Code: Alles auswählen

EnableExplicit

Define.l i, Ergebnis, URL_Laenge, Zaehlerlaenge
Define.s URL, Dateikopf

Ergebnis = InitNetwork()
URL = "https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page="
Dateikopf = GetHTTPHeader("https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=1")

For i = 152 To 190
  Zaehlerlaenge = Len(Str(i))
  URL = URL + i
  Debug URL
  ReceiveHTTPFile(URL, "E:\AnneWill\AnneWill_S_" + i + ".html")
URL_Laenge = Len(URL)
;Debug "Länge URL: " + URL_Laenge
;Debug "Zaehler: " + Zaehlerlaenge
URL_Laenge = Len(URL)-Zaehlerlaenge
URL = Left(URL, URL_Laenge)
Debug URL
Next

; https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=1
; https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=2
Nun möchte ich die Kommentare gerne in eine einzelne HTML-Datei speichern und zumindest die Tags zwischen

Code: Alles auswählen

<div class="pager">Zu Seite:
.
.
.
<div class="singlecomment"> 
aus den Quelltexten herausfiltern, da ich die Seitenangaben nicht benötige sondern alle Kommentare in eine einzige Datei verfrachten will.
Habe mich deshalb an den Funktionen ReadString, FindString usw versucht, bekomme es aber nicht hin eine einzelne Zeile anzeigen und deren Position bestimmen zu lassen, damit ich die Zeilen zwischen den beiden Suchparametern löschen kann.

Bräuchte deshalb etwas Hilfe dazu.
Danke vielmals.

System ist W7 64, PB ist 5.40 LTS
Inzwischen 61 Jahre alt.
Leider immer noch keine große Programmiererfahrung; nach Burn-Out vor fünf Jahren, starke Schwächen mit der Merkfähigkeit.
Körperlich und geistig schreitet der Verfall eben voran.
Trotzdem möchte ich versuchen etwas programmieren zu lernen und bin dankbar für jede Hilfe.
Benutzeravatar
GlassJoe
Beiträge: 108
Registriert: 11.06.2017 20:25
Computerausstattung: 2 x AMD Phenom II x4 945,2x Dell Latitude X300, Dell Latitude D410, Hp Compaq NC4400

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von GlassJoe »

Du schaffst das schon noch da richtig rein zu kommen :allright: ich weiss ja älter mann wird desto schwerer wird es mit dem lernen (sehe es ja an meinen Eltern die 70 sind, ist schwer für sie mit dem Smartphone) aber selbst ich der von Natur aus völlig untalentiert ist :lol: (links händer, kreative Gehirnhälfte ist aktiver als logische)
und grade mal 8 1/2 Jahre die Schule besucht hat (Rest hab ich blau gemacht, und im Rest davor auch oft) und extrem Probleme mit Gleichungen hatte, hab es irgendwann gerafft.

Ich habe sehr oft Parser wie du es brauchst geschrieben, bin mir sicher ich krieg das hin, und desshalb setz ich mich da mal rann.
https://www.geek.com/tech/a-commodore-6 ... s-1672510/
٩(̾●̮̮̃̾•̃̾)۶ __̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡ ̡͌l̡̡̡̡.___٩(- ̮̮̃-̃)۶
Benutzeravatar
GlassJoe
Beiträge: 108
Registriert: 11.06.2017 20:25
Computerausstattung: 2 x AMD Phenom II x4 945,2x Dell Latitude X300, Dell Latitude D410, Hp Compaq NC4400

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von GlassJoe »

Sorry hat ewig gedauert, bin total aus der Übung und müde :lol: :lol: :lol:

Hab ne halbe Stunde verloren weil da etwas so unlogisches passiert ist, daß ich mir absolute nicht erklären kann, hab 9384 x den Code debugged zwischen 2 Stellen und konnte ums verrecken nicht rausfinden, warum der Inhalt verloren ging, da es keinen Sinn ergeben hat, also musste ich etwas umschreiben.

Code: Alles auswählen

  
  EnableExplicit 
  
  Global NewList comment.s() ; wir erstellen eine LinkedList (siehe Anleitung)
  
  
  Procedure.i ParseFile(counter$)
    
    Define tmp_pos.i, counter_1.i, counter_2.i, Start_Pos.i, found.i
    Define tmp_comment$, tmp_string$, tmp_string_2$
    
    For tmp_pos.i = 0 To 3 ;wir erstellen 4 leere Zeilen in der Ausgabe Datei
      WriteStringN(1,"") 
    Next
    
    WriteStringN(1,"Kommentare Seite: "+counter$) ; jetzt schreiben wir unter die Leeren Zeilen von wo die Kommentare sind
    
    If ListSize(comment.s()) ; zählen ob was in der Liste ist
      
      ForEach comment.s() ; für jedes element in der list
        
        tmp_comment$ = comment() ;wir schreiben die linked list zeile in einen String (muss mann in dem fall eigentlich nicht
        
        counter_1 = CountString(tmp_comment$,Chr(34)+"username"+Chr(34)) ; wir zählen wie oft Username vorkommt, weil das später den Anfang eines kommentares markiert
        counter_2 = CountString(tmp_comment$,"<br>") ; wir zählen wie oft <br> vorkommt, weil das das Ende eines Kommentares ist
        
        ; Debug counter_1
        ; Debug counter_2
        
        If counter_1 <> 0 And counter_2 <> 0 ; falls beides ungleich 0 ist (wir wollen ja nur gültige Kommentar Zeilen)
          
          For tmp_pos = 1 To counter_1 
            
            ;tmp_pos ist die temporäre Position
            
            tmp_string$=StringField(tmp_comment$,tmp_pos,"<br>") ; mit diesem Befehl splitten wir die Zeile immer bei <br>
            
            ;Debug tmp_string$
            
            If tmp_string$ ; falls der ausgabe string nicht leer ist
              
              Start_Pos = FindString(tmp_string$,Chr(34)+"username") ; suchen wir den "username teil
              
              ;Debug tmp_string$
              
              If Start_Pos > 0 ; falls Start_pos nicht 0 ist, haben wir den Start Teil
                
                tmp_string_2$ = "" ;wir leeren hier erst mal diesen string, auch wenn es im moment unsinnig wirkt
                
                tmp_string_2$ = Right(tmp_string$, Len(tmp_string$) - Start_Pos) ;jetzt geben wir vom rechts eine gewisse anzahl
                ;von stellen zurück an tmp_string_2$ 
                
                If tmp_string_2$ ; und wenn tmp_string_2$ dann nicht leer ist
                  
                  tmp_string_2$ = RemoveString(tmp_string_2$,"username"+Chr(34)+">") ;entfernen wir die letzten störenden Teile
                  tmp_string_2$ = ReplaceString(tmp_string_2$,"</span> <p>","  ")   ;oder ersetzen sie
                  
                  ;Debug "FOUND" 
                  ;Debug tmp_string_2$
                  
                  found + 1 ; das wird später der Erfolgs Rückgabewert von der ParseFile() Funktion
                  
                  WriteStringN(1,"")
                  WriteStringN(1,tmp_string_2$) ; wir schreiben das Ergebniss in die Ausgabe Datei
                  
                EndIf
                
                
              EndIf
              
            EndIf 
            
          Next
          
        EndIf 
        
      Next
      
    EndIf 
    
    ;Debug "--------------------------------------------------------"  
    ;Debug "--------------------------------------------------------" 
    If ListSize(comment()) ;falls Liste einen Inhalt hat
      ForEach comment() ;lassen wir uns jede Zeile
        Debug comment() ;anzeigen
      Next      
    EndIf
    ;Debug "--------------------------------------------------------" 
    ;Debug "--------------------------------------------------------" 
    
    
    ProcedureReturn found ; wir veranlassen das die Procedure/Funktion verlassen wird, und als Rückgabe Wert den Inhalt von Found hat
    
  EndProcedure
  
  Procedure GetStuff(Startseite,Stopseite)
    
    If InitNetwork() = 0
      Debug "KONNTE NETZWERK NICHT INITIALISIERN"
      End
    EndIf
    
    Define URL$, URL_KON$, Http_HEADER$, counter$, line$
    Define tmp_pos.i, leer.i
    
    URL_KON$ = "https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page="
    Http_HEADER$ = GetHTTPHeader("https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=1")
    
    ; URL_KON$ -> KONSTANTER TEIL DER URL
   
    For tmp_pos = Startseite To Stopseite
      
      ;tmp_pos ist der zahler
      
      URL$=URL_KON$ ; bei jedem schleifen durchgang schreiben wir den konstanten teil der url wieder in URL$ rein
      
      counter$=Str(tmp_pos) ; umwandeln vom zähler in einen string
      
      ;Debug counter$
      
      URL$+counter$ ; anfügen vom Zähler String an die URL$
      
      ;Debug URL$
      
      If ReceiveHTTPFile(URL$, "E:\AnneWill\AnneWill_S_" + Str(tmp_pos) + ".html")
        
        If OpenFile(0,"E:\AnneWill\AnneWill_S_" + Str(tmp_pos) + ".html")
          
          leer=#True ; immer wenn wir eine der quellcode dateien öffnen setzen wir leer wieder auf "wahr"
          
          While Eof(0) = 0
            line$=ReadString(0)
            If line$
              leer=#False ;jetzt setzen wir leer auf Falsch/Unwahr
              AddElement(comment.s()) ; den Inhalt der Zeile in eine Linked List werfen
              comment.s() = line$  ; und hier werfen wir es dann erst rein
            EndIf 
          Wend
          
          If leer = #False ; falls leer unwahr ist
            
            If ParseFile(counter$) = 1 ;jetzt rufen wir die Funktion ParseFile auf, und übergeben ihr den Zähler String
              ; ES WURDEN KOMMENTARE GEFUNDEN
            EndIf  
            
          EndIf
          
          CloseFile(0) ; wir schliessen die Quellcode Datei
          
        EndIf
        
      Else
        
        Debug "DOWNLOAD DER QUELL CODE SEITE FEHLGESCHLAGEN
        Debug "-------->SEITEN ZÄHLER="+counter$
        
      EndIf
      
      ClearList(comment.s()) ; und löschen die Liste bevor die Schleife die nächste Kommentar Seite einliest
      
    Next 
    
    ; https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=1
    ; https://daserste.ndr.de/common/apps/php/sophorum/thread/view?cmsid=5f5a9397-2dcd-45e6-ada0-53960678a7f7&id_page=2
    
  EndProcedure
  
  If CreateFile(1,"E:\AnneWill\FERTIG.txt") = #False ;Wenn erstellen der Ausgabe Datei falsch ist
    Debug "KONNTE AUSGABE DATEI NICHT ERSTELLEN"
  Else
    GetStuff(152,160) ; Funktion (Prozedure) aufrufen, erster Paramter ist die Startseite
    CloseFile(1) ;nachdem der Teil von der GetStuff Funktion durch ist, schliesen wir die Ausgabe Datei
    MessageRequester("INFO","Fertig...",#PB_MessageRequester_Ok)
  EndIf
Ich hab dir alles in 2 Funktionen gepackt, und so gut es geht versucht zu kommentieren, und sogar EnableExplicit benutzt :D was ich sonst nieeeeeeeeeeeeeeeeee mache :lol:
https://www.geek.com/tech/a-commodore-6 ... s-1672510/
٩(̾●̮̮̃̾•̃̾)۶ __̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡ ̡͌l̡̡̡̡.___٩(- ̮̮̃-̃)۶
H.Brill
Beiträge: 357
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von H.Brill »

proggernewbie hat geschrieben: Nun möchte ich die Kommentare gerne in eine einzelne HTML-Datei speichern und zumindest die Tags zwischen

<div class="pager">Zu Seite:
.
.
.
<div class="singlecomment">

aus den Quelltexten herausfiltern, da ich die Seitenangaben nicht benötige sondern alle Kommentare in eine einzige Datei verfrachten will.
Schau mal in der Hilfe bei den Regular Espressions (Reguläre Ausdrücke).
Man könnte die Zeilen der Datei in einen langen String packen und dann mittels
reg. Ausdrücke suchen.
Da gibt es bestimmt auch Beispiele in PB, die TAGS (<...>) rausfiltern.
PB 6.10
proggernewbie
Beiträge: 19
Registriert: 23.03.2017 11:05
Computerausstattung: Win7 64bit, PureBasic 5.61 64bit
Linux Mint 19.1 64bit, PureBasic 5.71 64bit
VM (WinXP 32bit, PureBasic 5.71)
Wohnort: Kreis RE

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von proggernewbie »

Guten Morgen,

noch zur Erklärung: lese solche Sachen gerne auf dem Tablet oder Handy, wenn ich mit Bus und Bahn unterwegs bin, und da nerven viele Einzeldateien und bringen endlosen Datenmüll mit. Deshalb packe ich gerne so viel wie möglich in eine Datei.

@GlassJoe
vielen Dank für deinen Code und auch für deinen Zuspruch und deine Aufmunterung, aber puh. Das ist schon ziemlich harter Tobak für mich. Und gleich eine fertige Lösung präsentiert zu bekommen, war nicht meine Absicht. Nochmals danke dafür.
Ich hatte beabsichtigt die Position der Fundstellen zu berechnen und dann die Strings in der Länge von Anfang bis Ende aus den Fundstellen zu löschen. Leider saß ich nach Einfügen der Funktion FindString ratlos vor dem PC und wusste wieder einmal nicht weiter. Ist halt nicht so einfach für mich, habe sowieso seit einigen Jahren extreme Konzentrationsschwierigkeiten, und ich komme dann mit der Syntax und auch mit den Parametern nicht so recht klar. Gerade was Funktionen und Prozeduren angeht, stehe ich da ziemlich auf dem Schlauch.
Doch nun zu meinen Fragen:

Ist das Erstellen einer LinkedList notwendig oder ließen sich die gefundenen Positionen auch ohne den Einsatz der LinkedList aus den Quelltexten löschen?

Du zählst die Vorkommnisse von "username" und auch die von <br>. Die beiden CHR34 sind vermutlich die Anführungszeichen, die die beiden Anführungszeichen im Suchstring "username" maskieren. Ich hatte an dieser Stelle vor dem Einsatz von Findstring schon einmal die CHR10 und CHR 13 vor dem "username" eingesetzt, weil ich damit einen Zeilenumbruch erzwingen wollte. Hätte es mir erleichtert, die vorhirigen Strings am Ende der darüber stehenden Zeile abzuschneiden bzw zu löschen. Die Breaks <br> hatte ich nicht als Suchkriterium einbezogen, weil sie auch zwischen den einzelnen Abschnitten mal erscheinen, sondern meinen Suchstring genau vom Anfang dieser sich mit geänderten Seitenzahlen wiederholenden Auflistung versucht die Position zu ermitteln.

Weiter hatte ich überlegt einen Zeilenumbruch durch Suchen und Ersetzen im PB-Editor einzufügen (oder mit AOO Writer). Aber leider wurden keine Zeilenumbrüche eingefügt, oder wenn ich CHR(10)+CHR(13) eingefügt hatte nicht interpretiert, sondern waren im Seitentext dann lesbar. Wie könnte ich mittels Zeilenumbrüchen vor dem "username" den Kommentarbereich von den vorangehenden HTML-Tags trennen, damit mir ein leichteres Löschen möglich ist?

@ GlassJoe, @ H. Brill
Hatte mich auch schon einmal mit Regulären Ausdrücken beschäftigt, aber das ist mir viel zu hoch. Sobald ein String mehr Zeichen als drei enthält, und diese sich auch noch in Zahlen und Buchstaben aufteilen, muss ich kapitulieren. Habe dazu schon sehr viel auf einer Seite im Internet nach regex's gelesen und auch welche in der Eingabemaske "bauen" lassen. Leider geht da snicht bei diesen endlosen Strings.

Habe nur noch eine Frage zur Zeichenkodierung:
Nach dem Öffnen der Quelltexte im Editor (PB-Editor, Notepad usw werden Zeichen nur sehr komisch angezeigt. Habe dazu einen Screenshot gemacht. Weiß nur nicht, wie ich ihn hier ins Forum bekomme. Beim Anzeigen im Debugger stimmt unsere westdeutsche Textkodierung und ich kann problemlos alles lesen, wie müsste ich die Quelldateien öffnen und codieren, damit die Zeichen auch im Browser richtig angezeigt werden?

Erst einmal vielen Dank, muss mich etwas tiefer in den Code einlesen, um da wirklich durchzusteigen und werde mich bei Fragen noch einmal melden.
Schönen Tag noch.
Alfons

Ich wäre schon glücklich, wenn ich wenigstens mit den Stringfunktionen so weit fertig würde, dass ich wüsste, wann welche Parameter einzusetzen sind.
Inzwischen 61 Jahre alt.
Leider immer noch keine große Programmiererfahrung; nach Burn-Out vor fünf Jahren, starke Schwächen mit der Merkfähigkeit.
Körperlich und geistig schreitet der Verfall eben voran.
Trotzdem möchte ich versuchen etwas programmieren zu lernen und bin dankbar für jede Hilfe.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von Mijikai »

Vielleicht hilft das :)

Code: Alles auswählen

TestString.s = "<ABC>Hallo :)<XYZ>"

Procedure.s Extract(Input.s,Offset.i,SigStart.s,SigEnd.s,NoCase.b)
  Protected SE.i, SS = FindString(Input,SigStart,Offset,NoCase)
  If SS:SS + Len(SigStart):SE = FindString(Input,SigEnd,SS,NoCase):If SE
  ProcedureReturn Mid(Input,SS,SE-SS):EndIf:EndIf
EndProcedure

Debug Extract(TestString,0,"<ABC>","<XYZ>",#False)
proggernewbie
Beiträge: 19
Registriert: 23.03.2017 11:05
Computerausstattung: Win7 64bit, PureBasic 5.61 64bit
Linux Mint 19.1 64bit, PureBasic 5.71 64bit
VM (WinXP 32bit, PureBasic 5.71)
Wohnort: Kreis RE

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von proggernewbie »

Hallo Mijikai,

danke für deinen Codevorschlag.
Aber da steige ich nicht komplett durch.
Was bedeutet z.B. "SS:SS"? Was bedeutet da der Doppelpunkt? Mit Offset kann ich überhaupt nichts anfangen. Vermute nur, dass es sich dabei um eine Stelle im Speicher oder in der Datei/im String handelt, ab der gelesen/gesucht wird.
Von der Zeile

"If SS:SS + Len(SigStart):SE = FindString(Input,SigEnd,SS,NoCase):If SE"

einmal ganz abgesehen.

Ich erkenne, dass da die Länge berechnet wird. Aber danach verstehe ich nur Bahnhof. Ich bewundere Menschen, die solch elegante Codes schreiben können, aber mir würde es helfen auch sehr uneleganten und sperrigen Code zu schreiben, wenn ich damit mein Ziel erreichen könnte.
Wie kann ich z.B. den Teststring austauschen und meine Quelldatei öffnen und lesen?

Code: Alles auswählen

; TestString.s = "<ABC>Hallo :)<XYZ>"

Define.s filename, suchstring
Define.l i

filename = "E:\AnneWill\AnneWill_komplett_1.html"
Teststring = ReadFile(0, filename)
suchstring = "soforumCommentActionLinks"
If ReadFile(0, filename)       ; wenn die Datei geöffnet werden konnte, setzen wir fort...
    While Eof(0) = 0           ; sich wiederholende Schleife bis das Ende der Datei ("end of file") erreicht ist
      Debug ReadString(0)      ; Zeile für Zeile im Debugger-Fenster anzeigen
    Wend
    CloseFile(0)
  EndIf
  
  Procedure.s Extract(Input.s,Offset.i,SigStart.s,SigEnd.s,NoCase.b)
  Protected SE.i, SS = FindString(Input,SigStart,Offset,NoCase)
  If SS:SS + Len(SigStart):SE = FindString(Input,SigEnd,SS,NoCase):If SE
  ProcedureReturn Mid(Input,SS,SE-SS):EndIf:EndIf
EndProcedure

Debug Extract(TestString,0,suchstring,#True)
Wäre es so richtig?
Mir fehlt ein Parameter in der Klammer hinter "Debug Extract..."
Da verstehe ich eben den Code zu wenig

__________________________________________________
Code-Tags repariert
14.07.2017
RSBasic
Inzwischen 61 Jahre alt.
Leider immer noch keine große Programmiererfahrung; nach Burn-Out vor fünf Jahren, starke Schwächen mit der Merkfähigkeit.
Körperlich und geistig schreitet der Verfall eben voran.
Trotzdem möchte ich versuchen etwas programmieren zu lernen und bin dankbar für jede Hilfe.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von NicTheQuick »

Ich hab dir mal Mijakais Code kommentiert und so formatiert, dass man ihn lesen kann.

Code: Alles auswählen

; Gibt den Text zurück, der zwischen 'SigStart' und 'SigEnd' steht.
Procedure.s Extract(Input.s, SigStart.s, SigEnd.s, Offset.i = 0, NoCase.i = #PB_String_NoCase)
	Protected SE.i, SS.i
	
	; Suche Position von 'SigStart' ab 'Offset'
	SS = FindString(Input, SigStart, Offset, NoCase)
	If SS > 0
		; Falls 'SigStart' gefunden wurde, addiere zur Position noch die Länge
		; von 'SigStart'
		SS  = SS + Len(SigStart)
		
		; Suche ab dieser Stelle 'SigEnd'
		SE = FindString(Input, SigEnd, SS, NoCase)
		If SE > 0
			; Falls es gefunden wurde, extrahiere den Text zwischen
			; den beiden Positionen
			ProcedureReturn Mid(Input, SS, SE - SS)
		EndIf
	EndIf
	; In allen anderen Fällen gib einfach nichts aus
	ProcedureReturn ""
EndProcedure
Und ich hab die Reihenfolge der Parameter geändert, da Offset nicht so wichtig ist. Und NoCase habe ich standardmäßig auf #PB_String_NoCase gesetzt.
Bild
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von Bisonte »

Dein Suchstring um zu beenden ist nicht wirklich vorhanden. Ich habe also für das Beispiel unten -> "</div>" genommen.

Ich hoffe es ist kommentiert genug und verständlich ;)

Code: Alles auswählen

Filename.s = "E:\AnneWill\AnneWill_komplett_1.html"
NeuerFileName.s = "E:\MeinAusschnitt.txt"

ID = ReadFile(#PB_Any, Filename)                              ; Das File wird zum Lesen geöffnet
If ID                                                         ; Wenn es dann keine Probleme beim öffnen gibt
  FileInhalt.s = ReadString(ID, #PB_UTF8|#PB_File_IgnoreEOL)  ; Diese Zeile bewirkt das das komplette Dokument im String landet.
  CloseFile(ID)                                               ; und das File wieder schliessen
EndIf

; Hier nun die Suche Nach einem Tag (ab jetzt wird es etwas "formellastig")

; Wir suchen zuerst nach dieser Zeichenkette. Das CHR(34) ist der ASCII Code für das Anführungszeichen "
; Muss so gemacht werden, weil der Compiler sonst denkt, das der String dort aufhört !

ErsterSuchString.s = "<div class=" + Chr(34) + "pager" + Chr(34) + ">"

; Pos1 ist dann die Position ab der der gesuchte String in unserem "FileInhalt" String liegt. 
Pos1 = FindString(FileInhalt, ErsterSuchString)

If Pos1 ; Wenn also tatsächlich was gefunden wurde, das so aussieht ... (also Pos1 ist grösser als 0)
  
  Debug Pos1 ; Zeigt die Erste Position
  
  ; Jetzt bestimmen wir das Ende von dem Teil, den wir rausschneiden wollen
  ZweiterSuchString.s = "</div>"
  
  ; Hier suchen wir nun nach dem 2. String. Allerdings geben wir hier mit an (der Letzte 
  ; Parameter) dass wir an einer bestimmten Position anfangen wollen zu suchen, und nicht
  ; am Anfang...
  Pos2 = FindString(FileInhalt, ZweiterSuchString, Pos1) 
  
  Debug Pos2 ; Zeigt die 2. Position
  
  If Pos2 ; Wenn nun auch der 2. String gefunden wurde... (Pos2 ist ebenfalls grösser als 0)
    
    ; Kommen wir zum "Ausschneiden"
    ; Wir nehmen uns eine neue Stringvariable.
    ; Der Befehl Mid() schneidet uns nun das gewünschte Stück aus dem
    ; FileInhaltstring heraus. 
    Ausschneiden.s = Mid(FileInhalt, Pos1, (Pos2 + Len(ZweiterSuchString)) - Pos1)
    
    ; Man braucht die Startposition (Pos1) und die Länge... Die Länge errechnen wir
    ; hier mit Pos2 . Die muss Grösser als Pos1 sein. Das Len(ZweiterSuchString) zählt
    ; die Zeichen des SuchStrings mit hinzu, damit auch der Suchstring mit wegkommt.
    
    ; Und nun löschen wir das was wir da nun rauslesen konnten aus unserem FileInhalt
    FileInhalt = RemoveString(FileInhalt, Ausschneiden)
    
;     ; Man könnte das natürlich auch anders machen.
    
;     Pos1 = FindString(FileInhalt, ErsterSuchString) 
;     If Pos1                                         
;       LinkeSeite.s = Left(FileInhalt, Pos1 - 1) ; Hier wird erstmal bis zum Suchstring in einen Neuen string abgelegt
;       Pos2 = FindString(FileInhalt, ZweiterSuchString, Pos1) 
;       If Pos2
;         RechteSeite.s = Mid(FileInhalt, Pos2 + Len(ZweiterSuchString)) ; Und hier wird alles was nach dem Suchstring kommt in einen Neue Var abgelegt
;         FileInhalt = LinkeSeite + RechteSeite  ; Hier Pappen wir einfach beide zusammen und somit fehlt die mitte...
;       EndIf
;     EndIf
    
  EndIf
  
EndIf

; Nun ist das fertig und wir können das file speichern 
ID = CreateFile(#PB_Any, NeuerFileName)
If ID
  WriteStringN(ID, FileInhalt, #PB_UTF8)
  CloseFile(ID)
EndIf



PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
proggernewbie
Beiträge: 19
Registriert: 23.03.2017 11:05
Computerausstattung: Win7 64bit, PureBasic 5.61 64bit
Linux Mint 19.1 64bit, PureBasic 5.71 64bit
VM (WinXP 32bit, PureBasic 5.71)
Wohnort: Kreis RE

Re: Textdatei bzw. HTML-Datei editieren, Stringfunktionen

Beitrag von proggernewbie »

Hallo Nic,

danke vielmals, dadurch wird der Code für mich schon viel lesbarer und verständlicher.
Lediglich weiß ich nicht, wie ich statt des "input.s" die Datei einbinden kann, denn wenn ich dort die Variable für die Datei eintrage, erhalte ich die Meldung des Compilers "String erwartet". Wenn ich die Zeile einzeln aus der Textdatei lese, ist es doch die Funktion

Code: Alles auswählen

 ReadFile(0, filename) 
Anschließend iteriere ich doch mit

Code: Alles auswählen

 While Eof(0) = 0 
Zeile für Zeile durch die Datei bis ans Ende (EOF). Mit Wend wird die Schleife verlassen und mit CloseFile die Datei letztlich geschlossen.
Also müsste ich doch die Funktion ReadFile(0) auf die durch Mijakai erstellte Prozedur anwenden können. Nur weiß ich nicht, wie ich das mache.

Den String, der mit Mijakais Prozedur extrahiert wird

Code: Alles auswählen

 ProcedureReturn Mid(Input, SS, SE - SS) 
möchte ich ja gerade nicht haben, sondern diesen String aus den Quelltexten löschen, denn er kommt auf jeder Seite einmal vor. Dazu könnte ich ihn mit einem Zeilenumbruch ersetzen, oder ich drehe das Suchergebnis um und verwende nicht Mid sonder Laft und Right. Das macht mir jetzt nicht so das große Problem. Mein Problem ist das Einfügen eines Zeilenumbruchs (sollte doch +CHR(10)+CHR(13) sein, oder nicht), der auch als solcher interpretiert wird (PB-Editor, OpenOffice Writer und andere).
Ebenso möchte ich die einzelnen Quelltexte in eine Komplettdatei speichern und habe ein Probklem mit dem Anfügen dieser Zeilen.
Gibt es eine Funktion Append oder so ähnlich? Irgendwie schwirrt mir so etwas im Kopf herum und die Suche im Forum brachte mich nicht weiter.
Inzwischen 61 Jahre alt.
Leider immer noch keine große Programmiererfahrung; nach Burn-Out vor fünf Jahren, starke Schwächen mit der Merkfähigkeit.
Körperlich und geistig schreitet der Verfall eben voran.
Trotzdem möchte ich versuchen etwas programmieren zu lernen und bin dankbar für jede Hilfe.
Antworten