6
Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" ) 

スロー:System.ArgumentException:"[-]"-[xy]範囲を逆の順序で解析します。

\U00010000と\U0010FFFの16進値を見ると、最初の文字が0xd800 0xdc00、2番目の文字が0xdbff0xdfffになります。

ですから、私には本当に1つの問題があると思います。\ Uで形成されたUnicode文字が文字列内で2つの文字に分割されるのはなぜですか?

4

3 に答える 3

10

それらは代理ペアです。値を見てください-それらは65535を超えています。charは16ビット値にすぎません。たった16ビットで65536をどのように表現しますか?

残念ながら、.NETの正規表現エンジンが基本多言語面にない文字をどのように処理するか(または処理するかどうか)は、ドキュメントからは明らかではありません。(正規表現ドキュメントの\ uxxxxパターンは、C#エスケープシーケンスとしての\ uxxxxと同様に、0〜65535のみをカバーします。)

あなたの本当の正規表現はもっと大きいですか、それとも実際にそこに非BMP文字があるかどうかを確認しようとしていますか?

于 2008-12-12T20:24:24.073 に答える
5

.Net正規表現エンジンでこのような問題を回避するために、次のトリックを使用しています。次 のよう"[\U010000-\U10FFFF]"に置き換えられます[\uD800-\uDBFF][\uDC00-\uDFFF] 。この背後にある考え方は、.Net正規表現がコードポイントではなくコードユニットを処理するため、サロゲート範囲を通常の文字として提供することです。エッジを操作して、より狭い範囲を指定することもできます。例:[\U011DEF-\U013E07]は次のようになります。(?:\uD807[\uDDEF-\uDFFF])|(?:[\uD808-\uD80E][\uDC00-\uDFFF])|(?:\uD80F[\uDC00-uDE07])

読みやすく、操作も難しく、柔軟性もありませんが、回避策としては適しています。

于 2013-01-14T20:33:19.193 に答える
1

@ジョンスキート

それで、あなたが私に言っているのは、.netの正規表現ツールを使用してutf-16の範囲外の文字を照合する方法がないということですか?

完全な正規表現は次のとおりです。

^(\u0009|[\u0020-\u007E]|\u0085|[\u00A0-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF])+$

文字列に、yamlドキュメントで印刷可能なUnicode文字として定義されているものだけが含まれているかどうかを確認しようとしています。

于 2008-12-12T20:41:05.240 に答える