文字列から非ASCII文字を削除するにはどうすればよいですか?(C#で)


227

文字列から非ASCII文字を削除するにはどうすればよいですか?(C#で)


4
以下の sinelawの回答に従って、代わり非ASCII文字を置き換える場合は、代わりにこの回答参照してください
ボブソン

回答:


414
string s = "søme string";
s = Regex.Replace(s, @"[^\u0000-\u007F]+", string.Empty);

19
RegExに挑戦した人にとって、RegExパターンをプレーンな英語で書いてもらえませんか。言い換えれば、「^このない」、等...
メトロスマーフ

47
@Metro Smurf ^はnot演算子です。これは、一致するすべてのものではなく、一致しないすべてのものを見つけるように正規表現に指示します。\ u ####-\ u ####は、どの文字が一致するかを示します。\ u0000- \ u007Fは、utf-8またはunicodeの最初の255文字に相当します。これらは常にASCII文字です。したがって、(notのために)すべての非ASCII文字に一致し、一致するすべてのものを置換します。
ゴードンタッカー

41
印刷可能な文字の範囲は0020-007Eで、印刷不可能な文字を置き換える正規表現を探している人向け
Mubashar

1
@GordonTucker \ u0000- \ u007Fは、utf-8またはユニコードの最初の127文字
相当し

4
@full_prog_full約1分後に自分に返信し、255ではなく127であると自分に訂正したのはそのためです。:)
Gordon Tucker

125

正規表現を使用しない純粋な.NETソリューションを次に示します。

string inputString = "Räksmörgås";
string asAscii = Encoding.ASCII.GetString(
    Encoding.Convert(
        Encoding.UTF8,
        Encoding.GetEncoding(
            Encoding.ASCII.EncodingName,
            new EncoderReplacementFallback(string.Empty),
            new DecoderExceptionFallback()
            ),
        Encoding.UTF8.GetBytes(inputString)
    )
);

面倒に見えるかもしれませんが、直感的に理解できるはずです。.NET ASCIIエンコーディングを使用して文字列を変換します。UTF8は元の文字を表すことができるため、変換中に使用されます。EncoderReplacementFallbackを使用して非ASCII文字を空の文字列に変換します。


5
パーフェクト!これを使用して、RTFドキュメントに保存する前に文字列をクリーンアップしています。非常に高く評価。正規表現バージョンよりもはるかに理解しやすいです。
Nathan Prather、

21
あなたは本当に理解しやすいと思いますか?私にとって、実際には関係のないすべてのもの(フォールバック、バイトへの変換など)は、実際に起こっていることから注意をそらしています。
bzlm 2009年

21
ドライバーがややこしすぎるので、ハンマーを使うように言っているようなものです。
ブランドン

8
@ブランドン、実際には、この手法は他の手法よりもうまく機能しません。したがって、類推は、派手なiScrewDriver Deluxe 2000ではなく、普通の古いドライバーを使用することになります。:)
bzlm

10
利点の1つは、ASCIIをISO 8859-1または別のエンコーディングに簡単に置き換えることができることです。)
山本明

38

MonsCamusの意味は次のとおりです。

parsememo = Regex.Replace(parsememo, @"[^\u0020-\u007E]", string.Empty);

1
IMHOこの回答は、制御文字を削除するため、受け入れられた回答よりも優れています。
Dean2690 2017

15

削除したくないが、アクセント付きのラテン文字をアクセントなしの文字に実際に変換する場合は、次の質問をご覧ください。8ビット文字を7ビット文字に変換するにはどうすればよいですか?(つまり、ÜからU)


これが可能だとは思いもしませんでしたが、私にとってははるかに良い解決策です。このリンクを質問のコメントに追加して、他の人が簡単に見つけられるようにします。ありがとう!
ボブソン

11

philcruzの正規表現ソリューションに触発され、純粋なLINQソリューションを作成しました

public static string PureAscii(this string source, char nil = ' ')
{
    var min = '\u0000';
    var max = '\u007F';
    return source.Select(c => c < min ? nil : c > max ? nil : c).ToText();
}

public static string ToText(this IEnumerable<char> source)
{
    var buffer = new StringBuilder();
    foreach (var c in source)
        buffer.Append(c);
    return buffer.ToString();
}

これはテストされていないコードです。


1
理解できなかった人のために、これはC#4.0 LINQベースのソリューションです。:)

7
個別のToText()メソッドの代わりに、PureAscii()の3行目を次のように置き換えてみてください。return new string(source.Select(c => c <min?nil:c> max?nil:c).ToArray()) ;
agentnega

または、おそらくToText as:return(new string(source))。ToArray()-何が最も効果的かによって異なります。ToTextを拡張メソッドとして使用するのは、やはり流暢/パイプラインスタイルです。:-)
Bent Rasmussen

このコードは、非ASCII文字をスペースに置き換えます。:それらを取り除くには、変更を選択するにはreturn new string( source.Where( c => c >= min && c <= max ).ToArray() );
Foozinator

@Foozinatorこのコードを使用すると、ASCII以外の文字を置き換える文字を指定できます。デフォルトではスペースを使用しますが、それが.PureASCII(Char.MinValue)のように呼び出された場合、非ASCIIはすべて「\ 0」に置き換えられます-これは正確にそれらを削除するわけではありませんが、同様の結果になります。
Ulfius

5

正規表現は必要ありません。エンコーディングを使うだけ...

sOutput = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.ASCII.GetBytes(sInput));

5
これは動作しません。これはユニコード文字を取り除きません、それらを?に置き換えます。キャラクター。
デビッド

1
@Davidは正しいです。少なくとも私が????nacho??試したときに私は得ました:たまねこnachoなちモノ3.4で
nacho4d 14

1
文字を置き換える代わりに、それを削除する独自のEncodingクラスをインスタンス化できます。GetEncodingメソッドを参照してください
v

4

次のわずかに変更された範囲は、データベースからコメントブロックを解析するのに役立ちます。これは、CSVフィールドが混乱する原因となるタブやエスケープ文字と競合する必要がないことを意味します。

parsememo = Regex.Replace(parsememo, @"[^\u001F-\u007F]", string.Empty);

他の特殊文字や特定の句読点を避けたい場合は、ASCIIテーブルを確認してください


1
他のコメントに気づかなかった場合のために、印刷可能な文字は実際には@ "[^ \ u0020- \ u007E]"です。:ここではあなたが興味があれば、テーブルを参照するためのリンクですasciitable.com
scradam

3

拡張ASCII文字の解決策を探してここに来ましたが、見つかりませんでした。私が見つけた最も近いものはbzlmのソリューションです。しかし、これは127までのASCIIコードに対してのみ機能します(明らかに、彼のコードのエンコードタイプを置き換えることができますが、理解するのが少し複雑だったと思います。したがって、このバージョンを共有します)。拡張ASCIIコード(つまりISO 8859-1である255まで)で機能するソリューションを次に示します。

ASCII以外の文字(255より大きい)を見つけて取り除きます

Dim str1 as String= "â, ??î or ôu🕧� n☁i✑💴++$-💯♓!🇪🚑🌚‼⁉4⃣od;/⏬'®;😁☕😁:☝)😁😁///😍1!@#"

Dim extendedAscii As Encoding = Encoding.GetEncoding("ISO-8859-1", 
                                                New EncoderReplacementFallback(String.empty),
                                                New DecoderReplacementFallback())

Dim extendedAsciiBytes() As Byte = extendedAscii.GetBytes(str1)

Dim str2 As String = extendedAscii.GetString(extendedAsciiBytes)

console.WriteLine(str2)
'Output : â, ??î or ôu ni++$-!‼⁉4od;/';:)///1!@#$%^yz:

これがコードの実用的なフィドルです

要件に従ってエンコーディングを置き換えます。残りは同じままにする必要があります。


2
この文字列 "Ωcçã"からΩのみを削除するために機能した唯一のもの。どうもありがとうございました!
ラファエル・アラウージョ

2

これは最適なパフォーマンスではありませんが、非常に単純なLinqのアプローチです。

string strippedString = new string(
    yourString.Where(c => c <= sbyte.MaxValue).ToArray()
    );

欠点は、すべての「存続する」文字が最初に型の配列に入れられchar[]stringコンストラクターがそれを使用しなくなった後に破棄されることです。


1

私はこの正規表現を使用しました:

    string s = "søme string";
    Regex regex = new Regex(@"[^a-zA-Z0-9\s]", (RegexOptions)0);
    return regex.Replace(s, "");

16
これにより、句読点も削除されます。これは、誰かが望んでいない場合に備えてです。
Drew Noakes

1

この正規表現を使用して、ファイル名の不正な文字を除外します。

Regex.Replace(directory, "[^a-zA-Z0-9\\:_\- ]", "")

これは、ファイル名に使用できるすべての文字である必要があります。


1
いいえ。Path.GetInvalidPathCharsおよびPath.GetInvalidFileNameCharsを参照してください。したがって、数万の有効な文字があります。
Tom Blodget 2017年

あなたは正しい、トム。私は実際に一般的なものを考えていましたが、括弧と中括弧、およびこれらすべて-^%$#@!&+ =は省略しました。
user890332 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.