Sonderzeichen in Text-Datei zählen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

Hi,
ich habe ein kleines Problem undzwar wir mir von einem anderen Programm eine Text-Datei erstellt, in dieser Datei ist ein Sonderzeichen belibig oft enthalten. Mein Ziel ist es zu erfahren wie oft dieses Sonderzeichen in diesem Dokument vorkommt.
Mein Problem ist es jedoch, dass ich nicht die Unicodenummer des Zeichens weiß und es auch nicht kopieren kann und daher keinen Anatz habe.

Code: Alles auswählen


†
bla bla bal
bla bla bal
†
†
so in der Art sieht meine Text-Datei aus aber viele Tausend Zeilen lang (das Sonderzeichen ist ein anderes).

Sieht da irgendjemand eine Möglichkeit diese Zeichen zu zählen ?
Ich wäre für etwas Hilfe sehr dankbar.

Mit freundlichen Grüßen
TryToLearn
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

Also mein erster Ansatz ist so eine Konstelation.

Code: Alles auswählen

for line in obj:
    try:
        line.encode("UTF-8")
    except UnicodeDecodeError:
        count()
das funktioniert soweit auch aber ich denke da gibt es eine bessere Möglichkeit.
BlackJack

@TryToLearn: Erst mal die offensichtliche Frage: Wieso kannst Du das Zeichen nicht kopieren?

Ansonsten kannst Du die Datei doch einfach als Binärdatei öffnen und zum Beispiel die Bytewerte als Zahlen darstellen lassen. Also beispielsweise einen klassischen Hexdump erstellen. Dann siehst Du welche(n) Bytewert(e) dieses Zeichen in der Datei hat. Wenn man kein entsprechendes Programm zur Hand hat, wie zum Beispiel einen Hexeditor, lässt sich das ja auch leicht selber programmieren.

Edit: Wenn man sich Deinen Beispieltext mal nimmt und als UTF-8 speichert, dann sehen die Bytewerte wie folgt aus:

Code: Alles auswählen

bj@god:~$ cat test.txt
 
†
bla bla bal
bla bla bal
†
†
2
bj@god:~$ hd test.txt
00000000  20 0a e2 80 a0 0a 62 6c  61 20 62 6c 61 20 62 61  | .....bla bla ba|
00000010  6c 0a 62 6c 61 20 62 6c  61 20 62 61 6c 0a e2 80  |l.bla bla bal...|
00000020  a0 0a e2 80 a0 0a 32 0a                           |......2.|
00000028
Man sieht also dass das Zeichen mit der Bytefolge 0xe2 0x80 kodiert ist.
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

Das weiß ich leider auch nicht....

hier hab ich mal ein Bild in dem man das zeichen sieht

Bild
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

>>> text=""" 
... †
... bla bla bal
... bla bla bal
... †
... †
... """
>>> text.count('†')
3
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

das habe ich schon ausprobiert mein Problem ist ja dass ich das Zeichen nicht darstellen kann
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@TryToLearn: Zum ersten hast Du ja gar keine UTF-8 kodierte Datei, weshalb Du ja dann einen Decoding-Error bekommst.
Mit einem einfachen "print line" erhältst Du ja schon das Zeichen als Hex-Escape geliefert. Damit ist es kein Problem, an das Zeichen zu kommen.

PS: wahrscheinlich handelt es sich um das FormFeed-Zeichen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

TryToLearn hat geschrieben:hier hab ich mal ein Bild in dem man das zeichen sieht
Das sieht aus wie ein Ankh (☥) mit Unicode-Codepoint U+2625.

Ich habe damit übrigens keine Copy&Paste-Probleme.
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

@/me: leider ist es nicht dieses Zeichen.

@Sirius3: Also ich habe die Text-Datei einam aus UTF-8 codierte Datei und einmal als ANSI codierte Datei.
Ich verstehe jdeoch noch nicht ganz wie du das meinst, dass ich das Zeichen als Hex-Escape bekomme.

Nein es handelt sich leider nicht um das FormFeed-Zeichen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat Dir schon gezeigt, *wie* man an das Zeichen kommen kann :!:

Wo liegt also noch das Problem?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

ok in dem Fall mal von ganz vorne.
Ich habe ein pdf-Dokument mit knapp 1000 Seiten.
Dieses Dokument wandle ich mit der in dem Projekt xpdf enthaltenen Anwendung pdftotext in eine Text-Datei.
Diese Text-Datei durchsuche ich nach einem einmaligen key und verwerfe alles was nach dem key kommt.
pdftotext fügt nach jeder Seite dieses besondere Sonderzeichen ein die ich zählen möchte um die Seitenzahl herauszufinden, auf der sich der key befindet.

@Sirius3: Dieser Vorschlag kam einmal von dir. Meine bisherige Lösung funktioniert auf einer neuen Umgebung nichtmehr ganz wie erwünscht deshalb greife ich auf deinen Vorschlag zurück.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ja und? Auch nach deiner Komplettschilderung kann man nur sagen: BlackJack hat Dir schon gesagt, wie man an das Zeichen kommt! (Und damit kannst Du dann ja auch Deine Suchen durchführen)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Nach der Beschreibung mit ``xpdf`` bin ich mir auch fast sicher dass es sich um das „form feed”-Zeichen handelt wie Sirius3 ja schon vermutet hat, denn das würde sehr viel Sinn machen das nach jeder Seite einzufügen.

Edit: Macht nicht nur Sinn sondern steht auch in der Dokumentation zu ``pdftotext`` aus dem ``xpdf``-Paket. ;-)

Edit2: Und Du wirst nicht glauben wie dieses Zeichen unter DOS mit dem VGA-Zeichensatz angezeigt wird: ♀
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

Ersteinmal viel Dank für die Hilfe!

Wenn ich jetzt hingehe

Code: Alles auswählen

print x.count(u'\u2640'.encode("UTF-8"))
dann bekomme ich 0.

Bei allem anderen was ich versuche bkomme ich immer diesen Fehler

Code: Alles auswählen

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 527: ordinal not in range(128)
Es tut mir leid wenn ich euch langweile bzw. durch meine Unwissenheit nerve aber ich bin numal noch in der Lernphase.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das Zeichen ist ja auch kein Form Feed, sondern entspricht nur der Darstellung des Form Feeds im VGA Zeichensatz.

Du willst aber den Form Feed und dementsprechend

Code: Alles auswählen

x.count('\f')
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn Du ``print`` benutzt, kommt es einfach darauf an, ob die Shell die Zeichen überhaupt darstellen kann! Wenn Du unter Windows arbeitest, könnte das in einer Powershell klappen; die kann iirc UTF-8. Ansonsten wirst Du logischer Weise nie ein Zeichen sehen, welches die Shell nicht darstellen kann!

Alternativ kannst Du das aber in eine Datei schreiben (eben utf-8 codiert) und diese mit einem Editor öffnen, der UTF-8 Zeichen darstellen kann.

Der ``DecodeError`` kommt dann zustande, wenn Du (explizit oder *implizit*) einen Unicode-String in einen Bytestring codierst und dabei kein Encoding angibst oder eben das ``ASCII``-Encoding. Oftmals ist das *implizite* (z.B. durch ``print`` eines Unicode-Strings oder dem konkatenieren zwischen Unicode- und Bytestrings) das Problem. Du hast eben Zeichen darin, die *nicht* in ASCII darstellbar sind. Daher kracht der Versuch natürlich...

Zu den ganzen Zusammenhängen zwischen Encoding und Unicode schau Dir mal meine Signatur an :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

@cofi: Vielen vielen Danke das funktioniert super.

@Hyperion: Danke das ganze schau ich mir nochmal genauer an.

Und nochmal an alle danke für die Hilfe
Antworten