如何识别字符串是不是包含 unicode 字符?

Posted

技术标签:

【中文标题】如何识别字符串是不是包含 unicode 字符?【英文标题】:How to recognize if a string contains unicode chars?如何识别字符串是否包含 unicode 字符? 【发布时间】:2011-05-26 11:10:20 【问题描述】:

我有一个字符串,我想知道它里面是否有 unicode 字符。 (如果它完全包含ASCII)

我怎样才能做到这一点?

谢谢!

【问题讨论】:

我认为您需要告诉我们更多信息,因为 .NET 中的所有字符串都是 unicode。您是否担心在编码过程中会丢失一些字符?如果是这样,请告诉我们您打算将这些知识用于什么目的。 我想知道某些东西是否符合 ASCII...(完全符合) 使用正则表达式 - 这将是一个相关问题 正则表达式可用于替换或匹配。以下答案是关于替换的,但您也可以使用正则表达式进行匹配***.com/questions/7411438/… 【参考方案1】:

如果字符串仅包含 ASCII 字符,则使用 ASCII 编码的序列化 + 反序列化步骤应返回相同的字符串 所以 C# 中的单行检查可能看起来像..

String s1="testभारत";
bool isUnicode= System.Text.ASCIIEncoding.GetEncoding(0).GetString(System.Text.ASCIIEncoding.GetEncoding(0).GetBytes(s1)) != s1;

【讨论】:

它不适用于说俄语测试:System.Text.ASCIIEncoding.GetEncoding(0).GetString(System.Text.ASCIIEncoding.GetEncoding(0).GetBytes("фы")) != "фы" 返回 False。 我在控制台应用程序中测试了您的确切陈述,它为我返回 True。 我已经在 linqPad 中测试过了 - 它返回 false。【参考方案2】:

这是另一种不使用 lambda 表达式的解决方案。它在 VB.NET 中,但您可以轻松地将其转换为 C#:

   Public Function ContainsUnicode(ByVal inputstr As String) As Boolean
        Dim inputCharArray() As Char = inputstr.ToCharArray

        For i As Integer = 0 To inputCharArray.Length - 1
            If CInt(AscW(inputCharArray(i))) > 255 Then Return True
        Next
        Return False
   End Function

【讨论】:

ASCII 中只有 128 个字符,因此 > 255 似乎不正确。 有256个字符,包括基于此表的扩展ascii字符代码ascii-code.com【参考方案3】:

如果我的假设是正确的,您想知道您的字符串是否包含任何“非 ANSI”字符。您可以按如下方式得出这一点。

    public void test()
    
        const string WithUnicodeCharacter = "a hebrew character:\uFB2F";
        const string WithoutUnicodeCharacter = "an ANSI character:Æ";

        bool hasUnicode;

        //true
        hasUnicode = ContainsUnicodeCharacter(WithUnicodeCharacter);
        Console.WriteLine(hasUnicode);

        //false
        hasUnicode = ContainsUnicodeCharacter(WithoutUnicodeCharacter);
        Console.WriteLine(hasUnicode);
    

    public bool ContainsUnicodeCharacter(string input)
    
        const int MaxAnsiCode = 255;

        return input.Any(c => c > MaxAnsiCode);
    

更新

这将检测扩展的 ASCII。如果您只检测到真正的 ASCII 字符范围(最多 127 个),那么您可能会误报不表示 Unicode 的扩展 ASCII 字符。我已经在我的示例中提到了这一点。

【讨论】:

这是不正确的。 C# char 是 unicode UTF-16 字符。只有最多 127 个字符与 ASCII 中的字符相同。 ASCII 扩展范围将根据所使用的语言环境而有所不同,即 ANSI 不是扩展 ASCII。因此,对于英语 ISO-8859-1,字符将匹配 UTF-16,但在其他语言环境中它们不会是相同的字符。请参阅此处的比较表:en.wikipedia.org/wiki/ISO/IEC_8859。【参考方案4】:

ASCII 仅定义0-127 范围内的字符代码。 Unicode 被明确定义为与 ASCII 在同一范围内重叠。因此,如果您查看字符串中的字符代码,并且它包含高于 127 的任何内容,则该字符串包含非 ASCII 字符的 Unicode 字符。

请注意,ASCII 仅包含英文字母。因此,如果您(无论出于何种原因)需要对可能包含重音字符(例如西班牙语文本)的字符串应用相同的方法,那么 ASCII 是不够的,您需要寻找另一个区分因素。

ANSI 字符集 [*] 确实在128-255 范围内使用上述重音拉丁字符扩展了 ASCII 字符。但是,Unicode 与该范围内的 ANSI 不重叠,因此从技术上讲,Unicode 字符串可能包含不属于 ANSI 的字符,但具有相同的字符代码(特别是在128-159 范围内,正如您从表 I 中看到的那样链接到)。

至于执行此操作的实际代码,@chibacity 答案应该可以工作,尽管您应该修改它以涵盖严格的 ASCII,因为它不适用于 ANSI。

[*] 也称为拉丁语 1 Windows (Win-1252)

【讨论】:

【参考方案5】:

只要包含字符,就包含Unicode字符。

来自System.String

将文本表示为一系列 Unicode 字符。

public static bool ContainsUnicodeChars(string text)

   return !string.IsNullOrEmpty(text);

您通常不得不担心不同的 Unicode 编码:

    编码一个字符串一个具有特定编码的字节流。 解码字符串来自具有特定编码的字节流。

不过,一旦您进入字符串领域,字符串最初表示的编码(如果有的话)就无关紧要了。

字符串中的每个字符都被定义 通过 Unicode 标量值,也称为 Unicode 代码点或序数 Unicode 的(数字)值 特点。 每个代码点都经过编码 通过使用 UTF-16 编码,以及 的每个元素的数值 编码由 Char 表示 对象。

也许您可能还会发现以下问题:

How can you strip non-ASCII characters from a string? (in C#)

C# Ensure string contains only ASCII

Jon Skeet 的这篇文章:Unicode and .NET

【讨论】:

Unicode 是 ASCII 的超集。问题显然是关于如何确定字符串是否仅使用 ASCII 字符。所以这个答案对我来说似乎是不必要的迂腐...... @Zero3:问题的编辑是在我回答之后进行的。

以上是关于如何识别字符串是不是包含 unicode 字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查字节数组是不是包含 Java 中的 Unicode 字符串?

java如何把以unicode编码形式的字符串变成编码前的形式

PDF 中的 Unicode

Go36-36,37-字符串

确定字节数组是不是包含 ANSI 或 Unicode 字符串?

仅包含 ASCII 字符的 UNICODE 字符串是不是总是等于 ASCII 字符串?