2

文字列内の有効/許容される文字を制限する必要があります。与えられたルールは次のとおりです。

  • スペースはアンダースコアに置き換えられます
  • 長さは 256 に制限されています (コンパイラの制限)
  • ASCII コード 32 (スペース) と 126 (~) の間でなければなりません。
  • 次のいずれも含めることはできません。
    • : (コロン)
    • ; (セミコロン)
    • 、 (コンマ)
    • ' (一重引用符)
    • " (二重引用符)
    • \t (タブ)
    • \n (改行)
    • \r (キャリッジ リターン)
    • \\ (バックスラッシュ)

上記の規則を満たさないものはすべて、アンダースコアに置き換える必要があります。(長さの規則は、RegEx に同様に対処するものがない限り、最後に単純にトリミングできます。)

これで、たとえば英数字に対してこのようなクラスを作成することで、許容される文字を記述する方法がわかりました...

[a-zA-Z0-9]

...次に、このような Replace 呼び出しでその逆を使用します (先頭のカラットに注意してください)...

var cleanedString = RegEx.Replace(sourceString, "[^a-zA-Z0-9]", replacementString);

...しかし、範囲 (「' ' と '~' の間でなければならない」条件) と具体的に除外された文字の両方を処理するにはどうすればよいですか? このように「OR」演算として実行しますか?

var cleanedString = RegEx.Replace(sourceString, @"[^ -~]|[;:,'""\t\n\r\\]", replacementString);

注: それが ' ' (スペース) と '~' の間の範囲の開始方法ですか? どうにかしてスペースを明示的にエスケープする必要があるかどうかはわかりません。

より一般的には、質問のタイトルが尋ねるように、ルールは32を超えなければならないが、上限はなかったと言います。このような無制限の範囲をどのように指定できますか?

4

3 に答える 3

2

注:以下は、実際には要件の反対を行います -許可された文字を見つけます。許可されていないものについては、はい、質問で引用されている OR アプローチを使用します。

減算された文字クラスを使用できます (Microsoft.NET でサポートされています。Mono には、減算された文字クラスの処理に明らかにバグがある、または以前はバグがあったことに注意してください)。

バージョン 1

[\x21-\x7e-[\\:;,'"]]

説明:

  • [\x21-\x7e]= ASCII 33 (0x21) から 126 (0x7e) までの文字。
  • -[\\:;,'"]\= (エスケープ) :、、、、および;を除く。,'"

つまり、-[...]文字クラス内では、指定された文字が減算されます。

範囲は、スペース、タブ、キャリッジ リターン、および改行の削除を既に処理しているため、個別に指定する必要はありません。

はい、代わりに[\x20-\x7e]を使用できます[ -~]。スペースをエスケープする必要はありません。とにかくスペースが必要ないことを思い出してください。上記は次のように書くこともできます。

バージョン 2

[!-~-[\\:;,'"]]

!(ASCII 33) から~(ASCII 126) まで、減算された文字クラスの文字を除きます。

実際、私はバージョン 1 の読みやすさを好むと思います。

于 2013-07-09T23:06:57.110 に答える
2

3 番目の規則によって識別される文字の範囲は、ASCII 印刷可能文字として知られています。

という表現が使えます[\x20-\x7E]

Unicode 式を使用することもできます\P{C}

POSIX 文字クラス [:print:] は適切と思われますが、.NET の正規表現ではサポートされていないようです。私が試したときはうまくいきませんでした。

参照: http://www.regular-expressions.info/posixbrackets.html

更新: 以下は、OP で述べられている問題全体に対するより多くの解決策です。

static string StripInvalidCharacters(string input)
{
    return new System.Text.RegularExpressions.Regex(@"\s|[:;,'""\\]|\p{C}").Replace(input, "_");
}

: 実際には、このメソッドが呼び出されるたびに再作成するのを避けるために、このメソッドの外で Regex オブジェクトを作成することをお勧めします。

次の条件に一致する式を定義しました。

  • 任意のスペース文字 (スペース、タブ、リターン、または改行)
  • 次のいずれか: コロン、セミコロン、コンマ、一重引用符、二重引用符、バックスラッシュ
  • 任意の制御文字。元の回答で前述した大文字の P の代わりに、式 \p{C} で小文字の p を使用したことに注意してください。これは、大文字の P が「すべての制御文字」を意味する {C} 部分を否定するためです (参照: http://msdn.microsoft.com/en-us/library/20bw873z.aspx )。したがって、\P{C} という表現は基本的に「制御文字ではないすべての文字」を意味しますが、このコード例では、文字をアンダースコアに置き換えているため、「制御文字である任意の文字」に一致させたいので、そのために \p{C} 式を使用します。
于 2013-07-09T21:51:56.240 に答える