私がC#で文字列を持っていると想像してください:「私はあなたに会わない」
これらの「’」記号を削除したい(何もないなどに置き換えたい)。
どうすればよいですか?
その「ジャンク」は、誰かが UTF-8 データを ISO 8859-1 または Windows-1252 として、おそらく繰り返し解釈したように見えます。
’ は、シーケンス C3 A2、E2 82 AC、E2 84 A2 です。
Windows 1252 では、このシーケンスは E2 80 99 なので、文字は U+2019、RIGHT SINGLE QUOTATION MARK (') である必要があります。
バイト配列、Encoding.UTF8 および Encoding.GetEncoding(1252) を使用して複数のパスを作成し、ジャンクを最初に入力されたものに正しく戻すことができます。UTF-8 データが誤って Windows-1252 として解釈された 2 つの場所を見つけるために、処理を確認する必要があります。
ラテン文字以外の文字を削除すると、意図的に国際化のサポートが中断されます。
名前に「â」が入っている可哀想な人を忘れないでください。
"I Don’t see ya..".Replace( "’", string.Empty);
そもそもそのジャンクはどうやってそこに入ったのですか?それが本当の質問です。
これは、標準の文字エンコーディングを使用してデータベースに格納されている Windows の文字セットを扱う文字エンコーディングの問題と似ているように見えます。誰かがウィルに反対票を投じたのを見たが、彼には一理ある。当面の課題は解決しているかもしれませんが、課題であればキャラクターの組み合わせは無限大です。
本当にこれを行う必要がある場合は、正規表現がおそらく最良の解決策です。
ただし、なぜこれを行う必要があるのかを考えることを強くお勧めします。リストにある望ましくない文字の少なくとも一部は、他の言語で完全に有効であり、有用であり、それらを除外するだけで、少なくとも一部の国際ユーザー。スウェーデン人として、 å、ä、ö の文字を正しく処理できないシステムがどれだけ嫌いかは、いくら強調してもしすぎることはありません。
Regex.Replace(your_string, regex, "") を検討してください - それが私が使用するものです。
各文字を順番にテストして、有効な英字または数字であるかどうかを確認し、そうでない場合は文字列から削除します。文字テストは非常に簡単です。使用するだけです...
char.IsLetterOrDigit;
などなど、他にもいろいろありますのでどうぞ。
char.IsSymbol;
char.IsControl;
Regex.Replace("文字列", "[^a-zA-Z ]","");
その正規表現 ([^a-zA-Z ]) はほとんどの言語で機能するはずですが、これは C# で行う方法です。
[編集: 正規表現のスペースを忘れた]
これらの文字のASCII/整数コードは、通常のアルファベットの範囲外になります。シークして空の文字に置き換えます。文字列にはReplaceメソッドがあると思います。
EXIFダンプでadobeによってスローされた無関係なジャンクで同じ問題がありました。私は1時間かけて率直な答えを探し、ここではうまくいかなかった多くの中途半端な提案を試みました。
このスレッドは、私がこれまでに読んだどのスレッドよりも、「どのようにしてそこにたどり着いたのか?」、「誰かの名前にこの文字が含まれているとしたら?」、「本当に国際化を破りたいのか?」などの深く掘り下げた質問でいっぱいでした。
このジャンクがどのようにしてここに到達したかを推測し、さまざまな文字エンコーディング スキームの進化を説明する、印象的な博識の展示がいくつかありました。その人は、それがどのようになったのか、または標準化団体が何をしようとしているのかではなく、それを削除する方法を知りたがっていました。このトリビアは興味深いかもしれません。
私は正しい答えを与える小さなプログラムを書きました。主な概念を言い換える代わりに、自己完結型の動作する (少なくとも私のシステムでは) プログラム全体と、ジャンクを核攻撃するために使用した出力を次に示します。
#!/usr/local/bin/perl -w
# This runs in a dos window and shows the char, integer and hex values
# for the weird chars. Install the HEX values in the REGEXP below until
# the final test line looks normal.
$str = 's: “Brian'; # Nuke the 3 werid chars in front of Brian.
@str = split(//, $str);
printf("len str '$str' = %d, scalar \@str = %d\n",
length $str, scalar @str);
$ii = -1;
foreach $c (@str) {
$ii++;
printf("$ii) char '$c', ord=%03d, hex='%s'\n",
ord($c), unpack("H*", $c));
}
# Take the hex characters shown above, plug them into the below regexp
# until the junk disappears!
($s2 = $str) =~ s/[\xE2\x80\x9C]//g; # << Insert HEX values HERE
print("S2=>$s2<\n"); # Final test
Result:
M:\new\6s-2014.1031-nef.halloween>nuke_junk.pl
len str 's: GÇ£Brian' = 11, scalar @str = 11
0) char 's', ord=115, hex='73'
1) char ':', ord=058, hex='3a'
2) char ' ', ord=032, hex='20'
3) char 'G', ord=226, hex='e2'
4) char 'Ç', ord=128, hex='80'
5) char '£', ord=156, hex='9c'
6) char 'B', ord=066, hex='42'
7) char 'r', ord=114, hex='72'
8) char 'i', ord=105, hex='69'
9) char 'a', ord=097, hex='61'
10) char 'n', ord=110, hex='6e'
S2=>s: Brian<
ノーマルです!!!
私が遭遇したもう1つの実用的で実用的な提案: iconv -c -t ASCII < 6s-2014.1031-238246.halloween.exf.dif > exf.ascii.dif
不要なもののブラックリストを使用するか、できればホワイトリスト (セット) を使用してください。ホワイト リストを使用すると、文字列を繰り返し処理し、ホワイト リストにある文字のみを結果の文字列にコピーします。あなたは削除すると言いましたが、その方法は、(R) から読み取る 1 つと (W) に書き込む 2 つのポインターを持つことです。
I Donââ‚
W R
コンマがホワイトリストにある場合、この場合、コンマを読み取り、それを Ã の場所に書き込み、両方のポインタを進めます。UTF-8 はマルチバイト エンコーディングであるため、ポインタを進めるだけでアドレスが追加されるわけではありません。
C では、事前定義された関数 (またはマクロ) のいずれかを使用してホワイト リストを取得する簡単な方法: isalnum、isalpha、isascii、isblank、iscntrl、isdigit、isgraph、islower、isprint、ispunct、isspace、isupper、isxdigit。この場合、コースのセットではなく、ホワイト リスト機能を使用して送信します。
通常、あなたのようなデータを見ると、メモリの破損、または期待するエンコーディングがデータが入力されたものと異なることを示唆する証拠を探します。
/アラン