【问题标题】:Get index of first non standard english character获取第一个非标准英文字符的索引
【发布时间】:2015-08-20 14:07:39
【问题描述】:

当我发现一个不属于标准英文字母的字符时,我正在尝试处理一个字符串并将其分成两部分。例如This is a stríng with áccents.,我需要知道第一个或每个带重音字符的索引(í)。

我认为解决方案介于 System.Text.EncodingSystem.Globalization 之间,但我错过了一些东西......

重要的是要知道它是否是带重音的字符,如果可能的话排除空格。

void Main()
{
    var str = "This is a stríng with áccents.";
    var strBeforeFirstAccent = str.Substring(0, getIndexOfFirstCharWithAccent(str));
    Console.WriteLine(strBeforeFirstAccent);

}

int getIndexOfFirstCharWithAccent(string str){
    //Process logic
    return 13;
}

谢谢!

【问题讨论】:

  • 到目前为止,您尝试完成了什么?我认为return 13 根本没有任何尝试。
  • 对不起,我不知道该怎么做。我希望有人能做到。
  • @GrantWinney 这是一种非常幼稚的看法。 ASCII 是一个非常有限 的字符集,而 C#/.NET 默认情况下甚至不使用 ASCII。 C#/.NET 使用 UTF-16 格式的 Unicode,它的 non-standard English 字符远多于 128-165 的 ASCII 范围。 (例如,一个带有变音符号的e 怎么样,这与 ASCII é 或 ASCII 130 完全不同,它甚至不适用于我的 PC。)
  • @YuvalItzchakov,从 TDD 的角度来看,return 13 是一个字符串的完美代码。只有在引入第二个字符串时才需要使代码更复杂。
  • @YuvalItzchakov,很抱歉我在开玩笑。

标签: c# linq character-encoding globalization diacritics


【解决方案1】:

正则表达式[^a-zA-Z ] 将查找非重音罗马字母和空格以外的字符。

所以:

var regex = new Regex("[^a-zA-Z ]");
var match = regex.Match("This is a stríng with áccents.");

将返回í

match.Index 将包含它的位置。

【讨论】:

  • 虽然我不是正则表达式的粉丝,但这对他们来说是个好地方。另外,请注意:这只会返回 first 实例。如果你需要其他人,那么你必须抓住他们。 (也就是说,这个答案仍然符合问题的确切标准,为此 +1。)您可能还需要考虑将 0-9 添加到该否定块以及各种其他符号。
  • @EBrown,我同意。正则表达式有它们的位置,但它们经常被过度使用。我对自己的回答担心的是,例如字符串中的, 会破坏它。这是一个答案,但我正在寻找其他人发布更好的答案;)
  • 我刚刚完成了我的非正则表达式解决方案,我认为它们都有很大的优点。 (您的 Regex 解决方案的代码行数更少,我的非 Regex 解决方案不会错误地标记符号。)
  • var regex = new Regex("[^\u0000-\u007F]"); var matches=regex.Matches("This is a string with áccents.");
【解决方案2】:

另一种可能的解决方案(固定/改编自 Cortright 的回答)是枚举 Unicode 对。

const string input = "This is a stríng with áccents ?.";
byte[] array = Encoding.Unicode.GetBytes(input);

for (int i = 0; i < array.Length; i += 2)
{
    if (((array[i]) | (array[i + 1] << 8)) > 128)
    {
        Console.WriteLine((array[i] | (array[i + 1] << 8)) + " at index " + (i / 2) + " is not within the ASCII range");
    }
}

这将打印所有超出允许的 ASCII 值范围的数值的列表。 (我将ASCII的原始定义为0-127。)

就个人而言,我推荐 David Arno 的解决方案。我只是把它作为一个潜在的替代品发布。 (如果您对其进行基准测试,它可能会更快。同样,它可能也更易于管理。)

更新:我刚刚对其进行了测试,它似乎仍然可以正确识别较高范围内的字符 (U+10000 - U+10FFFF),因为 not 被允许。事实上,这是因为代理对也在 ASCII 范围之外。唯一的问题是它将它们识别为两个字符对,而不是一个。

输出:

237 at index 13 is not within the ASCII range
225 at index 22 is not within the ASCII range
55378 at index 30 is not within the ASCII range
57186 at index 31 is not within the ASCII range

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    相关资源
    最近更新 更多