Wie kann ich Nicht-ASCII-Zeichen in Textdateien finden?

10548
Marcus Leon

Gibt es ein Werkzeug, mit dem eine kleine Textdatei gescannt werden kann und nach beliebigen Zeichen gesucht werden kann, die nicht im einfachen ASCII-Zeichensatz enthalten sind?

Ein einfaches Java- oder Groovy-Skript würde ebenfalls ausreichen.

5
Es kann dorthin verschoben werden, obwohl dies der Meinung ist, dass Programmierer bei bestimmten Programmieraufgaben direkt von Interesse wären. (ZB wo ich gerade bin) Marcus Leon vor 12 Jahren 0
Es handelt sich nicht um eine Programmierfrage und ist daher nicht thematisch. Sie sind schon lange genug hier, um das zu erfahren, aber wenn nicht, lesen Sie bitte die [FAQ] (http://stackoverflow.com/faq), um zu erfahren, welche Fragen hier thematisiert werden. :) Ken White vor 12 Jahren 0
Sie können natürlich 'grep' mit einer negierten Charakterklasse verwenden. Tom Zych vor 12 Jahren 0
Alles, was nicht den Weg des "grep" [^ \ x00- \ xFF] "oder seines moralischen Äquivalents ** gehen wird, wenn man vorhandene Werkzeuge verwendet und kein neues Programm ** schreibt, ist nichts anderes als ein verrückter Overkill. tchrist vor 12 Jahren 0
@christ, guter Punkt. Obwohl ich ein Problem damit habe - http://stackoverflow.com/questions/7258299/grep-regex-doesnt-work-with-cygwin-on-windows Marcus Leon vor 12 Jahren 0
Verwenden Sie `grep -P '[^ \ x00- \ xFF]'` oder `perl -ne ', wenn / [^ \ x00- \ xFF] /'`. Beachten Sie, dass die `-P`-Option von grep keine echten Perl-Regexes akzeptiert. tchrist vor 12 Jahren 0
@ tchrist: Läuft ASCII nicht von 00 bis 7F? Tom Zych vor 12 Jahren 0
@Tom: Ja. Ich ahmte nur nach, was das OP tat, was mir später klar wurde, dass es keinen Sinn machte. tchrist vor 12 Jahren 0

5 Antworten auf die Frage

2
Tom Zych

Nun, es ist nach einer Stunde immer noch hier, also kann ich es auch beantworten. Hier ist ein einfacher Filter, der nur Nicht-ASCII-Zeichen aus seiner Eingabe druckt und den Exit-Code 0 (falls vorhanden) und 1 (falls vorhanden) gibt. Liest nur von der Standardeingabe.

#include <stdio.h> #include <ctype.h>  int main(void) { int c, flag = 0;  while ((c = getchar()) != EOF) if (!isascii(c)) { putchar(c); flag = 1; }  return flag; } 
Danke, zufällig eine Java-Version? :) Marcus Leon vor 12 Jahren 0
Nein, mach kein Java, sorry. Tom Zych vor 12 Jahren 0
@Marcus: Monolingualismus ist ungefähr so ​​umweltfreundlich wie jede andere Monokultur. tchrist vor 12 Jahren 1
1
jonathan.cone

Führen Sie einfach $ JDK_HOME / bin / native2ascii für die Textdatei aus und suchen Sie in der Ausgabedatei nach "\ u". Ich gehe davon aus, dass Sie es finden wollen, damit Sie es trotzdem entkommen können, und dies wird Ihnen einen Schritt ersparen. ;)

0
awfulHack

Ich habe keine Ahnung, ob dies echt ist, indem ich jedes Zeichen in ein int lege und einen Haken benutze, um Dinge zu identifizieren, die fehlschlagen. Ich bin auch zu faul, um dies in Java zu schreiben, also habe ich einige Groovy

def chars = ['Ã', 'a', 'Â', 'ç', 'x', 'o', 'Ð'];  chars.each{ try{ def asciiInt = (int) it } catch(Exception e){ print it + " "} } 

==> Ã ç

0
Nathan Moos

In Java (vorausgesetzt, der String wird als erstes Befehlszeilenargument angegeben:

public class Main { public static void main(String[] args) { String stringToSearch = args[0]; int len = stringToSearch.length(); for (int i = 0; i < len; i++) { char ch = stringToSearch.charAt(i); if (ch >= 128) // non-ascii { System.out.print(ch + " "); } } System.out.println(); } } 

Um dies zu Ihrem eigenen zu machen, ersetzen Sie es stringToSearchmit dem, was Sie brauchen.

0
OverZealous

Ein einfaches grooviges Beispiel:

def str = [ "this doesn't have any unicode", "this one does ±ÁΘ·€ÔÅ" ]  str.each { if( it ==~ /[\x00-\x7F]*/ ) { println "all ascii: $it" } else { println "NOT ASCII: $it" } } 

Es ist so einfach wie dieses Stück hier: it ==~ /[\x00-\x7F]*/

Bearbeiten: Ich habe vergessen, eine Version für Dateien hinzuzufügen. Hoppla:

def text = new File(args[0]).text if( text ==~ /[\x00-\x7F]*/ ) { println "$ is only ASCII" System.exit(0) } else { println "$ contains non-ASCII characters" System.exit(-1) } 

Diese Version kann als Befehlszeilenskript verwendet werden und enthält einen Beendigungsstatus, damit sie verkettet werden kann.

Es macht keinen Sinn, die gesamte Datei in den Speicher zu lesen. Beachten Sie, dass ** EVERY SINGLE STRING EVER CREATED ** mit etwas wie `/ [\ x00- \ xFF] * /` übereinstimmt, so wie jeder einzelne String auch mit `/ a * /`, sogar `" xxx "` übereinstimmt. Null oder mehr bedeutet, dass Sie mit 0 zufrieden sind. Und `/ [\ x80- \ xFF] /` ist kein ASCII! Sie müssen mit `/ ^ [\ x00- \ x7F] + $ /` übereinstimmen, um alle ASCII-Zeichen zu sein. Eine normale Regex-Engine mit der grundlegendsten Unicode-Unterstützung würde einfach `\ p ` vs `\ P ` verwenden. tchrist vor 12 Jahren 0
@christ Ich freue mich über das Feedback. Natürlich wäre es effizienter, die Datei zu streamen. Die ursprüngliche Frage wurde jedoch speziell zum Scannen einer ** kleinen Datei ** gestellt. Ihr Kommentar zum Regex ist falsch, einfach weil ich meinen Code getestet habe, bevor ich ihn gepostet habe. Tut mir leid, wenn mein Bereich falsch ist - das könnte ein gültiger Kommentar sein, aber Ihr Kommentar ist unnötig aggressiv und unhöflich. Ich habe lediglich ein funktionierendes Groovy-basiertes Beispiel gegeben, da die Frage es erwähnte. OverZealous vor 12 Jahren 0
Außerdem müssen Sie die leere Zeichenfolge angeben, oder leere Dateien werden als Nicht-ASCII angezeigt. Ich denke das ist falsches Verhalten. OverZealous vor 12 Jahren 0
Nop, ASCII ist die Codepunkte 0 bis 127. Ihr Muster entspricht 0 bis 255. Es ist daher falsch. tchrist vor 12 Jahren 0
Ich sollte mir nicht die Mühe machen, zu antworten, aber ich muss auf zwei Dinge hinweisen: Erstens hätten Sie einfach darauf hingewiesen und einen Fix vorgeschlagen, und ich hätte meinen Vorschlag aktualisiert. So funktioniert StackExchange - Antworten können bearbeitet und bereinigt werden. Zweitens ist es witzig, dass Sie eine so große Sache mit dem Sortiment machen, da es genau das ist, das Sie oben vorgeschlagen haben! Es ist in Ordnung, aber ich verstehe, dass Sie lieber jemanden niederschlagen, als hilfreich zu sein. OverZealous vor 12 Jahren 0