Suchen und ersetzen im Arbeitsspeicher

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Benutzeravatar
balu
********
Beiträge: 3810
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen und ersetzen im Arbeitsspeicher

Beitrag von balu »

Hallo!

Ja, ja!
Hin und wieder sind es doch nur kleinigkeiten die einem das Leben erst erschweren, aber auf der anderen Seite auch erleichtern können. Hört sich paradox an, aber so ist es mir grad eben ergangen.

Ich zitiere mich mal selbst.
balu hat geschrieben: Mi, 30.05.2018 10:43 das die gezeigte mögliche Lösung für den Fall ist, wenn man sich nicht sicher ist wieviele Ersetzungen gemacht werden müssen.
Und gemeint war damit folgender Code.
balu hat geschrieben: Mi, 30.05.2018 00:23

Code: Alles auswählen

sub tete2
	dim NCRdez(1 to 2, 1 to 13) as String

	NCRdez(1,1) =  "µ" : NCRdez(2,1) =  "µ"
	NCRdez(1,2) =  "¼" : NCRdez(2,2) =  "¼"
	NCRdez(1,3) =  "½" : NCRdez(2,3) =  "½"
	NCRdez(1,4) =  "¾" : NCRdez(2,4) =  "¾"
	NCRdez(1,5) =  "Ä" : NCRdez(2,5) =  "Ä"
	NCRdez(1,6) =  "Ö" : NCRdez(2,6) =  "Ö"
	NCRdez(1,7) =  "Ø" : NCRdez(2,7) =  "Ø"
	NCRdez(1,8) =  "Ü" : NCRdez(2,8) =  "Ü"
	NCRdez(1,9) =  "ß" : NCRdez(2,9) =  "ß"
	NCRdez(1,10) =  "ä" : NCRdez(2,10) =  "ä"
	NCRdez(1,11) =  "ö" : NCRdez(2,11) =  "ö"
	NCRdez(1,12) =  "ø" : NCRdez(2,12) =  "ø"
	NCRdez(1,13) =  "ü" : NCRdez(2,13) =  "ü"

sTmpNameX = "Wäster Überflutet Örtliche Augenärzte, und nu is nix mehr weiß."
'____________________________________________________________________________________________	
	ix = 0	
	for r = 1 to Len(sTmpNameX)
		if Mid(sTmpNameX, r, 2) = "&#" then
			ix = ix + 1
		end if						
	next r
print "IX = Insgesamt zu ersetzende NCRdez-Codes:  " & ix ' <- Diese Zeile braucht man nicht unbedingt. Kann also gelöscht werden.
'____________________________________________________________________________________________
	sTmpX = sTmpNameX
		for r2 = 1 to ix				
			for r3 = 1 to 13
				sTmpX2 = REPLACE(sTmpX,  NCRdez(1, r3),  NCRdez(2, r3))
				sTmpX = sTmpX2									
			next r3						
		next r2				
	PRINT sTmpX	
end sub
Den Zähler 'ix' braucht man nicht. Den kann man sich einsparen. Und außerdem kann man den eigentlichen Ersetzungs-Code so ändern, das man gar nicht auf einen vergleichenden Text a-la '= "&#" then' angewiesen ist.
Hier ist der komplette Ersetzungs-Code.

Code: Alles auswählen

		for r2 = 1 to Len(sTmpX)				
			for r3 = 0 to 12
				sTmpX2 = REPLACE(sTmpX,  aUTF(0, r3),  aUTF(1, r3))
				sTmpX = sTmpX2									
			next r3						
		next r2
Mehr braucht es nicht :-)

Aber warum '0 to 12'?
Ganz einfach.
Das ist die maximale größe des Array. Mal einfach ausgedrückt.

Code: Alles auswählen

aUTF = DimArray(1, 12)
Und was hat das nun mit "dem Leben erschweren" zu tun?
Tja, das ist wie folgt.
Ein UTF-Code kann ja folgendes sein 'ä'. Was dem kleinem 'ä' entspricht.
Wenn man jetzt aber aus "unerklärlichen" Gründen auch noch das in einem Text stehen hat &Oslash;' (steht für Ø), dann ist es Essig mit 2 Zeichen abzählen. Also war das für mich zu anfangs ein Problem. Doch nach ein paar tests kam ich auf die "simple" gezeigte Lösung. Und wär ich nicht auf dies kleine Problem gestoßen, hätte ich mich noch mit der bisherigen alten Lösung rumgeschlagen. Jetzt erleichtert mir die Lösung das leben. :-)

Hier noch mal der komplette Code mit einem Beispieltext.

Code: Alles auswählen

Sub Main
aUTF = DimArray(1, 12)
aUTF(0,0)= "ä"  : aUTF(1,0)= "ä"
aUTF(0,1)= "Ä"  : aUTF(1,1)= "Ä"
aUTF(0,2)= "ö"  : aUTF(1,2)= "ö"
aUTF(0,3)= "Ö"  : aUTF(1,3)= "Ö"
aUTF(0,4)= "ü"  : aUTF(1,4)= "ü"
aUTF(0,5)= "Ãœ"  : aUTF(1,5)= "Ü"
aUTF(0,6)= "ß"  : aUTF(1,6)= "ß"
aUTF(0,7)= "Ë?"  : aUTF(1,7)= "½"
aUTF(0,8)= "Ľ"  : aUTF(1,8)= "¼"
aUTF(0,9)= "ľ"  : aUTF(1,9)= "¾"
aUTF(0,10)= "Å™"  : aUTF(1,10)= "ø"
aUTF(0,11)= "Å ~"  : aUTF(1,11)= "Ø"
aUTF(0,12)= "&Oslash;"  : aUTF(1,12)= "Ø"

sTmpX = "Ronden &Oslash; 50 mm Automatenstahl 11SMn30+C gesägt Länge 50 mm"
'____________________________________________________________________________________________		
		for r2 = 1 to Len(sTmpX)				
			for r3 = 0 to 12
				sTmpX2 = REPLACE(sTmpX,  aUTF(0, r3),  aUTF(1, r3))
				sTmpX = sTmpX2									
			next r3						
		next r2
	PRINT sTmpX	
End Sub


Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

Re: Suchen und ersetzen im Arbeitsspeicher

Beitrag von marcel_at_work »

Hallöchen Balu,

ich habe den Thread jetzt nur mal kurz überflogen und hoffe, es richtig verstanden zu haben, daß du Webcontent bearbeiten möchtest?

Ich hatte vor ein paar Jahren mal ein Projekt für die Extrahierung von Webcontent in eine Datenbank und dies wie folgt realisiert:

Per...

Code: Alles auswählen

Dim myFileProp(0) as new com.sun.star.beans.PropertyValue
myFileProp(0).Name = "Hidden"
myFileProp(0).value = True
oTempQuelltext = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, myFileProp())
oQuelltextCursor = oTempQuelltext.Text.createTextCursor()
... wurde im Hintergrund eine unsichtbare Writer-Datei geöffnet und mit...

Code: Alles auswählen

iNumber = Freefile
Open sWebUrl For Input As iNumber
While NOT eof(iNumber)
	Line Input #iNumber, sTextzeile
	If sTextzeile <> "" Then sQuelltext = sQuelltext & sTextzeile & Chr(10)
Wend
Close #iNumber
... der Text vom Host in eine String-Variable hineingeladen.
Anschließend wurde durch eine Schleife über eine Datenbanktabelle aller Codierungen (analog zu deinem Array, aber mit komplettem Unicode-Zeichensatz) einfach...

Code: Alles auswählen

Do While oResultSignCodes.next()
	sQuelltext = replaceString(sQuelltext,oResultSignCodes.getString(2),oResultSignCodes.getString(4))
Loop
oQuelltextCursor.String = sQuelltext 'Übertragung des neuen Quelltextes in das nicht sichtbare Writer-Dokument
... aufgerufen.
"ReplaceString()" aus der Bibliothek Tools ersetzt alle Zeichenfolgen aus der Quell-Zeichenfolge auf einmal. Man benötigt also nur eine Anweisung pro Code-Zeichen und muss nicht in der Quell-Zeichenfolge suchen.

Und da der Text sowieso im Writer-Dokument vorliegt, kann man anschließend leistungsstarke "reguläre Ausdrücke" benutzen, falls man den Text noch weiterbearbeiten möchte.

Liebe Grüße,

Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
Benutzeravatar
balu
********
Beiträge: 3810
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen und ersetzen im Arbeitsspeicher

Beitrag von balu »

Hallo Marcel,
daß du einfach nur Zeichen in einem String austauschen möchtest?
Stimmt.

ich habe den Thread jetzt nur mal kurz überflogen
Dann ist dir wohl das hier entgangen, gleich zu Anfang in meinem Eröffnungsbeitrag.
balu hat geschrieben: Dieser Text befindet sich aber weder in Calc noch im Writer, sondern er wird aus einer Online HTML-Seite (WWW) ausgelesen und er befindet sich in folge dessen im Arbeitsspeicher.
Mit anderen Worten es setzt wohl als minimum das hier voraus.

Code: Alles auswählen

Open sWebUrl For Input As iNumber
Anschließend wurde durch eine Schleife über eine Datenbanktabelle aller Codierungen (analog zu deinem Array, aber mit komplettem Unicode-Zeichensatz) einfach...
[...]
... aufgerufen.
Und wie sieht diese Datenbanktabelle aus?

An 'ReplaceString()' hatte ich jetzt gar nicht gedacht. Ich glaube das ich mal damit gearbeitet hatte, aber auch meine Probleme damit hatte. Ist jetzt auch nicht so wichtig (meine Probleme damit).

Dein Vorschlag ist wohl vielleicht nicht ganz uninteressant, aber ohne zu wissen wie die Datenbanktabelle auszusehen hat ist es eigentlich "nutzlos". Du sprichst ja auch von 'einer Datenbanktabelle aller Codierungen', aber wenn ich dich jetzt richtig verstehe müstte ich wohl mit 2 solcher Datenbanktabellen arbeiten, da es sich, siehe meinen letzten Code, um ZWEI verschiedene UTFs handelt. Oder wie verhält sich das bei dir?

Und außerdem ging es mir ja auch im wesentlichem nur darum, nur bestimmte Zeichen zu ersetzen von denen ich weiss das sie vorkommern. Ich muss also keine Tabelle mit 256 Verglerichszeichen/Austauschzeichen besitzen oder intergrieren um nur 13 Zeichen zu behandeln. Und ich brauch auch nicht den Umweg über eine zusätzliche Writerdatei zu gehen, da es ausschließlich NUR um diese paar Zeichen geht, und nicht mehr. Der Umweg mit der Writerdatei mag wohl je nach Situation gar nicht mal so verkehrt sein, aber in diesem Falle ist das am Thema vorbei: "Suchen und ersetzen im Arbeitsspeicher"

Das alles soll jetzt nicht heißen das ich deine Bemühungen nicht würdige, aber momentan sehe ich keinen Vorteil für mich. Was aber schon interessant wäre, wenn Du eine Beispieldatei hier anhängen würdest. Denn mein letzt geposteter Code ist ein so genannter "Stand-allone-Code" der so direkt ausführbar ist, um selber mal ein bisschen zu experimentieren. Deine Beschreibung ist aber so nicht lauffähig. Deine Beispieldatei würde ich dann aber meinerseits als erlaubtes "Off-Toppic " betrachten. :lol:



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

Re: Suchen und ersetzen im Arbeitsspeicher

Beitrag von marcel_at_work »

Hallöchen balu,

ich könnte dir die besagte Datenbanktabelle schicken, aber zur Ansicht benötigt man einen installierten MySQL-Server. Ich kann sie selbst nicht mehr einsehen, da ich die Technik des damaligen Projektes nicht mehr benutze (mir zu umständlich).

Mir ist nach Ansicht des restlichen Programmcodes ein kleiner Fehler in meiner Argumentation aufgefallen: Die besagte Tabelle besteht aus allen möglichen Codierungen, mit ID, Zeichen, Unicode, HTML,... usw. (aber der grundlegende Aufbau ist identisch mit deinem Array, nur eben mit weiteren Dimensionen)
In meiner oben beschriebenen Schleife gab es zwar, wie gesagt, nur einen Schleifendurchlauf, aber zwei Werte, die pro Zeile ggf. ausgetauscht/ersetzt werden mussten:

Code: Alles auswählen

ID	Zeichen	Unicode	HTML	UTF8	...
1	ä	U+00E4 	&#228;	C3A4
Aber diese Werte könnten natürlich auch alle samt untereinander in einer einzigen Tabellenspalte (oder auch einem Array) stehen:

Code: Alles auswählen

ID	Zeichen	Code
1	ä	U+00E4 
2	ä	&#228;
...
Mir ist jetzt leider nicht bekannt, welche Probleme du mit "ReplaceString()" hattest, aber mit dieser Funktion könnte man in deiner REPLACE()-Prozedur die äussere Schleife weglassen?!

Diese ganze Sache mit dem Writer-Dokument habe ich deshalb aufgeführt, weil du in der Einleitung davon geschrieben hast, "Inhalte von einer Internetseite zu extrahieren" und dies bedeutet für mich erst einmal, den Inhalt von HTML-TAGS zu filtern, was sich eben mit dem SearchDescriptor im Writer-Dokument am weitaus effektivsten lösen lässt, wie z.B. mit:

Code: Alles auswählen

'Extrahierung des HTML-"Body" aus dem Quelltext:
SearchDesc.SearchString = "<body(\n*|\t*|.*)*</body>"
FoundDesc = oTempQuelltext.findFirst(SearchDesc)
If Not isNull(FoundDesc) Then
	sHtmlBody = FoundDesc.String
End If
Aber falls dies gar nicht so zutrifft, kannst du meine Ideen einfach ignorieren! :lol:

Liebe Grüße,

Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
Benutzeravatar
balu
********
Beiträge: 3810
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen und ersetzen im Arbeitsspeicher

Beitrag von balu »

Nabend Marcel,

so so. Es gibt jetzt hier keine Datenbank. Macht aber nix, da ich im groben den Aufbau verstehe.

Die Sache mir 'ReplaceString()' werd ich mir vielleicht mal noch genauer anschauen, je nach dem wie meine Lust dazu ist. Eilt ja auch nicht.

Der Code für "HTML-TAGS zu filtern" hört sich interessant an. Werd mal schauen ob ich den bei einer anderen Sache verwenden kann. Aber Lust ....

Ich bleib erstmal bei meinem letzten Code. Er kann so leicht *ratz-fatz* in andere Makros übernommen werden.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Antworten