Gesundes neues Jahr allseits auf Nickles.de,
bin auf der Suche nach einem Programm, daß in Texten Ersetzungen mit dem Platzhalter * (für beliebige Anzahl aller Zeichen) umgehen kann.
Ich will exemplarisch
<a id="abs3" name="abs3"></a> in
<a id="abs3"></a> mit
" name="*"
ändern. Auch " name="???" macht es nicht.
Bisher habe ich kein Helferlein gefunden, wer kennt eines für WIN oder Linux?
Falls jemand sowas als VBA für Word 2016 hat, wäre das auch eine Lösung.
Besten Dank
Anwendungs-Software und Apps 14.492 Themen, 73.651 Beiträge
Unter Linux geht das z.B. mit sed.
Mit VBA usw. habe ich leider keinen Plan;-)
Danke für den Tipp, das sehe ich mir heute Abend an, mangels Linux an der Arbeit ;-)
Guten Abend,
das sollte klappen mit dem TausendSasser 'sed'.
Allerdings finde ich nirgendwo beschrieben, wo die zu bearbeitende Datei liegen soll, damit 'sed' die finden kann. :-(
sed 's/name="*">/xyz>/g' input.txt > output.txt
sed: input.txt kann nicht gelesen werden: Datei oder Verzeichnis nicht gefunden
Wo erwartet 'sed' denn Eingabedateien?
Oder wo liegt das Programm selbst?
Danke für die Unterstützung
Das sed selber installiert ist, siehst Du daran, dass es ja grundsätzlich arbeitet, sonst könnte es nicht meckern;-)
Du musst natürlich in das Verzeichnis wechseln, in welchem der Text liegt, denn Du bearbeiten willst. Da der sicherlich nicht input.txt heisst, musst Du auch den richtigen Namen angeben.
Hast Du z.B. im Verzeichnis Dokumente die Datei namens sternchenda.txt, wechselst Du zuerst mit cd Dokumente in das richtige Verzeichnis. Der Prompt sollte dann so enden:
~/Dokumente$
Dort kannst Du dann z.B. mit ls prüfen, ob die Datei sternchenda.txt existiert (den senkrechten Strich - die Pipe - erzeugst Du auf einer deutschen Tastatur durch das Drücken der Tasten AltGr und unten links mit den Winkelpfeilen neben der Umschalttaste:
ls -l | grep sternchen*
Wird dabei die so beniemte Datei angezeigt, steht einem Bearbeiten mittels Stream-Editor nichts mehr im Wege. Um die Sternchen zu ändern, musst Du diese allerdings als Sonderzeichen maskieren mittels vorangestelltem Slash:
sed -e 's|abs3|/*|g' sternchenda.txt
Um die Originaldatei zu behalten, kannst Du mittels Umleitung eine neue Datei mit dem geänderten Inhalt erstellen:
sed -e 's|abs3|/*|g' sternchenda.txt > sternchenda_1.txt
Nach erfolgreichem Durchlauf kanst Du ebenfalls mit ls - l die Existenz der neuen Datei prüfen:
ls -l | grep sternchen*
Dann sollten Dir sowohl die alte unveränderte Datei als auch die neue angezeigt werden.
Danke für die Nachhilfe, ich mache viel zu wenig mit der Konsole.
Nun habe ich einige Syntaxe probiert nur leider erfolgt die gewünschte Textersetzung nicht.
Ich werde mir die Dokumentation nochmal genauer ansehen.
Vielleicht habe ich mich in der Anfrage auch nicht präzise ausgedrückt.
Der * soll als Multi-Platzhalter alle Zeichen im Text erfassen, so wie bei der Suche mit * oder ?.
Gutn8 für heute und vielen Dank
Foxy
Ist das eine einmalige Aktion (mit genau diesem einen Ersetzungsproblem) oder muss das regelmäßig (mit verschiedenen Dateien und verschiedenen Ersetzungen) gemacht werden?
Wie viele Vorkommen des betreffenden Ausdrucks musst Du denn in diesem Fall ersetzen?
Ich könnte mir vorstellen, eine solche Ersetzung u.U. auch mit Excel zu erledigen.
Falls das für Dich in Frage kommt, könnte ich Dir dabei helfen.
Guten Morgen,
danke erstmal für das Interesse.
Es handelt sich um die Suche einer Lösung für viele nachfolgende Dateien.
Es werden ältere HTML-Dokumente aktualisiert und der Code bereinigt und verschlankt.
Dabei sind mehrere 100 Anker und Verweise je Datei zu bereinigen. Per Hand wirst Du krank dabei. ;-)
Ich bin offen für jede Lösung, manchmal muß man auch 'um die Ecke' denken, weil meißt einfache Lösungen ganz nahe sind, nur man sieht sie nicht, wie den Wald vor lauter Bäumen.
Eine Lösung per Excel wäre bestimmt elegant, daran habe ich noch nicht gedacht. Mit Access VBA wäre es auch eine Überlegung wert, ggf in mehreren Durchläufen.
Also nehmen wir ein Code-Schnipsel wie etwa:
<a id="p28" name="p28">
<a id="a292" name="a292">
<a id="f1a280" name="f1a280">
Übrig bleiben soll nur der erste Teil incl. dem zweiten " und daran das abschließende >.
Also <a id="p28"> als Bsp. für die erste Zeile von oben.
Soweit der Plan ;-)
VG Foxy
Für .html-Dateien benutze ich Notpad++, und das hat eine ziemlich gute suchen... ersetzen-Funktion.
Danke für den Hinweis,
mit Notepad2 oder ++ schreibe ich den HTML-Code. Nur mit den Platzhaltern * und ? kann es nicht umgehen.
Leider. VG Foxy
In die Spalte A schreibst Du die ursprünglichen HTML-Fragmente.
In Spalte B wird mit einer Zeichenkettenoperation der gewünschte Inhalt extrahiert.
Der Ausdruck in Zelle B1 im oben gezeigten Beispiel lautet:
=LINKS(A1;FINDEN(" ";A1;4)-1)&RECHTS(A1;LÄNGE(A1)-FINDEN(">";A1;4)+1)
Viel Erfolg!
Gruß, mawe2
Intesressanter Ansatz, der bei kurzen Texten funktioniert aber nicht bei fortlaufendem Text von immerhin 135kB und 1567 Zeilen.
Die von Dir angesprochene HTML-Fragmente kann ich nicht extrahieren, Excel muß schon den gesamten Quelltext schlucken, was es nur mit Schmerzen macht. :-(
So geil wie Excel ist, nur dafür ist es eben nicht gemacht ;-)
btw: Geht nicht gibt's nicht, man muß nur das richtige Werkzeug haben. Da scheint mir zunächst das 'sed' vom ersten Hinweis erfolgversprechender zu sein.
cu Foxy
Die von Dir angesprochene HTML-Fragmente kann ich nicht extrahieren, Excel muß schon den gesamten Quelltext schlucken, was es nur mit Schmerzen macht. :-(
135 kB / 1567 Zeilen sollten doch für Excel kein Problem sein.
Der Ausdruck für die Ersetzung muss dann natürlich ggf. noch angepasst werden.
So geil wie Excel ist, nur dafür ist es eben nicht gemacht ;-)
Es ist nicht explizit dafür gemacht, lässt sich aber gut dafür "missbrauchen" :-)
Ich erledige diverse HTML-Aufgaben gern mit Excel. Das hat mir in verschiedenen Szenarien schon gute Dienste geleistet.
Für die explizite Bearbeitung von HTML-Code kann ich neben Notepad++ auch noch Visual Studio Code empfehlen.
Sollte mit verschiedenen Anwendungen möglich sein die RegEx unterstützen.
Brauchst das nur eine einzelne Datei oder für mehrere?
Es handelt sich um ein älteres HTML-Dokument, daß aktualisiert werden soll, dann folgen weitere.
Es wird von <... HTML 4.01> charset=windows-8859-15 auf <!DOCTYPE HTML> charset=utf-8 umgestellt und bereinigt.
Das ist übrigens mein Privatspaß. Und wenn dann mal die dt. Sprache mit Umlauten usw. wieder Geltung erlangt, stelle ich das gerne wieder um. :-))
Gutn8 für heute und vielen Dank
Foxy
Es handelt sich um ein älteres HTML-Dokument, daß aktualisiert werden soll, dann folgen weitere.
Dann solltest Du auf jeden Fall schauen wie Du das automatisieren kannst.
mit Notepad2 oder ++ schreibe ich den HTML-Code. Nur mit den Platzhaltern * und ? kann es nicht umgehen.
Mit Notepad++ ist ein Suchen und Ersetzen mit Regulären Ausdrücken möglich.
Wenn Du alle Name-Attribute entfernen willst, dann kannst Du dafür den Suchausdruck
/ name="[^"]*"/
verwenden (/ weglassen; [^"]* sucht nach einer beliebigen Anzahl von Zeichen die kein " sind; Eine Suche nach beliebigen Zeichen würde viel längeres Matches produzieren).
Evtl. willst Du aber auch die name-Attribute nur dann entfernen wenn der Attribut-Wert identisch zum Attribut-Wert in id ist? Auch das wäre mit Regulären Ausdrücken möglich (zumindest so lange Du eine einheitliche Struktur hast. Sonst wird es aufwändiger).
Ungestestet: /( id="([^"])*") name="\2*"/\1/g
( \2 als Backreferenz sucht den selben Attributwert in der zweiten Klammer, \1 ersetzt den Gesamtstring durch den Inhalt der ersten Klammer, also dem Id-Attribut mit Wert)
Guten Morgen,
oh ja. das sollte mit Notepad2 und -++ gehen. Das wäre eine sehr komfortable Lösung für alle Tage und viele Bedarfe. Nur stimmt irgendwas mit der Sytax nicht, wie so oft.
/ name="[a-zA-Z0-9_]"/ oder / name="[.*]"/ machen es auch nicht.
Leider habe ich außer https://regexlearn.com/learn/regex101
noch keine URL gefunden, die da hilfreich sein könnte.
Ich bleibe dran.
Vielen Dank allen Helfern
LG Foxy
Nur stimmt irgendwas mit der Sy[n]tax nicht, […] / name="[a-zA-Z0-9_]"/ oder / name="[.*]"/ machen es auch nicht.
/[a-zA-Z0-9_]/ matched nur ein einzelnes Zeichen. Mit einem * dahinter kannst Du beliebig viele, mit einem + dahinter mindestens eine Wiederholung eines Teilausdrucks beschreiben.
Schlage daher vor es mal zu probieren mit / name="[a-zA-Z0-9_]*"/
Nur stimmt irgendwas mit der Sy[n]tax nicht, […] oder / name="[.*]"/ machen es auch nicht.
/[.*]/ wird wahrscheinlich nicht so funktionieren wie Du Dir das vorstellst, da die Zeichen innerhalb der eckigen Klammern (nicht) speziell interpretiert werden.
Gut zum Ausprobieren ist https://regex101.com/ sehr schön - dort bekommst Du auch direkt noch eine Erklärung des Ausdrucks. Links kannst Du von Suchen zu Ersetzen umschalten.
Auch schon um sich mit den Möglichkeiten von Regulären Ausdrücken vertraut zu machen ist https://alf.nu/RegexGolf
Ansonsten mal nach RegEx CheatSheet suchen für eine kompakte Zusammenfassung. Da hast Du aber vor allem sehr viele Angebote…
Geht nicht gibt's nicht - alter Nickles-Spruch!
Für interessierte Mitleser: In der Beschäftigung mit regex führte der Suchstring
' name="p(.?.{0})">' (ohne Apostophe)
mit Ersetzen durch '>'
unter Linux LMDE5 mit Notepad++, Kate, LibreOffice und Bluefisch, immer unter dem Suchmuster 'Finden und Ersetzen', 'Regulärer Ausdruck (PCRE)' zum Ergebnis. Unter Windows noch nicht probiert.
Der Befehl ist zwar nicht optimal, führt aber in mehreren Schritten zur gewünschten Änderung im Code.
Als erstes wird ein Leerzeichen gesucht.
Dann der Text 'name="p'.
In '(.?)' alle Zeichen 1 mal ohne Wiederholung.
Mit der Zahl in '.{7}' wird die Anzahl der Wiederholungen gesteuert, in meinem Fall 0 bis 7.
Als letztes wird die Zeichenkette '">' gesucht.
Ersetzen durch '>' nicht vergessen, sonst ist das '>' weg.
Das war mein Versuchstext:
1x <p><a id="p4a1" name="p4">§ 41</a><br>
2x <p><a id="p41a5" name="p41">(5)</a> Die untere
4x <p><a id="p41a7" name="p41a7">(7)</a> <span>
6x <p><a id="p4a1s2" name="p41a2s4">(2)</a> Für die
7x td><a id="p56a1z10" name="p56a1z10">10</a>.</td>id
Hilfreiche, wenn auch teils widersprüchliche Links waren:
https://wiki.selfhtml.org/wiki/Regul%C3%A4rer_Ausdruck
https://danielfett.de/2006/03/20/regulaere-ausdruecke-tutorial/
https://www.massiveart.com/de-de/blog/regex-zeichenfolgen-die-das-entwickler-leben-erleichtern
https://ahkde.github.io/docs/v1/misc/RegEx-QuickRef.htm
http://www.regexe.de/
https://regex101.com/
hat mit sich selbst prima fünktioniert, die dort erzeugten Suchstrings bei mir jedoch in keinem Anwendungsprogramm, es ist dennoch zum Lernen gut geeignet.
RegEx ist ein mächtiges Werkzeug, meine Lösung noch nicht zufriedenstellend aber zielführend - ich bleibe dran.
Vielen Dank allen, die mir geantwortet haben und MN für diese tolle langjährige Internetpräsenz!
Foxy
In '(.?)' alle Zeichen 1 mal ohne Wiederholung.
Das passt so nicht: ? steht für 0 oder 1 mal.
Mit der Zahl in '.{7}' wird die Anzahl der Wiederholungen gesteuert, in meinem Fall 0 bis 7.
{7} steht für exakt 7 Vorkommen. {0,7} würde 0 bis 7 erlauben.
(.?.{0})
Warum da nicht einfach .{0,8} ?
Bzw. nicht wie schon zu Beginn vorgeschlagen [^"]+ ?
https://regex101.com/ hat mit sich selbst prima fünktioniert, die dort erzeugten Suchstrings bei mir jedoch in keinem Anwendungsprogramm, es ist dennoch zum Lernen gut geeignet.
Kann ich nicht so recht nachvollziehen.
auch teils widersprüchliche Links
Kann ggf. an unterschiedlichen Detailausprägungen der RegEx-Syntax liegen. Die einfachen Teile sind aber eigentlich überall gleich.
Danke für die Korrekturhinweise.
name="p(.?.{0,7})">
funktioniert prima, hatte ich so nicht gefunden.
name="p(.?.{0,7})"> funktioniert prima
Diese Formulierung ist aber weiterhin sehr ungünstig: '.?' könntest Du auch als '.{0,1}' schreiben und '.{0,1}.{0,7}' matched die selben Eingaben wie '.{0,8}', wobei die Auswertung bei getrennter deutlich aufwändiger ist (2*8 statt 9 Möglichkeiten).
Und ich bin mir ziemlich sicher, dass auch
name="p([^"]*)">
funktionieren würde, aber deutlich robuster ist.
Ja, ' name="p([^"]*)">' funktioniert auch.
Leider erschließt sich mir nicht, was der Klammernausdruck '([^"]*)"' bewirkt.
Ich lese den so:
() --> Gruppe, aus einem oder mehreren Zeichen.
[^"] --> Einmal Anführungszeichen am Anfang auslassen.
* --> Keines bis alle Zeichen von 0 bis unendlich.
Das verstehe ich nicht und würde es deshalb nicht so aufbauen. Der String schließt ja auch im Ergebnis das erste ' '' ' nicht aus. Weshalb ist es robuster?
' name="p(.?.{0,10})">' gefällt mir besser, weil ich das lesen kann und weiß was der String macht.
Z.B. macht '(.?.{0,20})' genau das, was ich erwarte.
Also ich kann die Suchstrings nur so aufbauen, wie ich es verstehe. Bin ja auch gerade am Anfang.
Danke für Deine Hinweise Borlander.
Foxy
() --> Gruppe, aus einem oder mehreren Zeichen.
Die Klammern könnte man auch weglassen, sofern man nicht an anderer Stelle auf diesen Teilausdruck referenzieren möchte. Sowas hatte ich AFAIR am Anfang mal vorgeschlagen...
[^"] --> Einmal Anführungszeichen am Anfang auslassen.
* --> Keines bis alle Zeichen von 0 bis unendlich.
Darfst Du beides nicht getrennt betrachten! Das * bezieht sich immer auf das Element davor. '.*' beliebige Anzahl von beliebigen Zeichen, 'a*' beliebig lange Folge von kleinen As (z.B. aaaaaaaaaaaa), '(Foxy)*' (z.B. FoxyFoxyFoxyFoxy, aber auch eine leere Zeichenkette) die beliebig häufige Wiederholung Deines Usernamens, '[^"]*' eine beliebige Anzahl aller Zeichen außer dem Anführungszeichen.
<a id="abs3" name="p"><i id="x"></i> Titel</a>
Dort würde bei Deinem Ausdruck die komplette Zeichenkette
name="p"><i id="x">
ersetzt. Also deutlich mehr als soll. Btw.: RegEx sind i.d.R. greedy, matchen also immer so viel wie möglich.