C# 中插入符号位置、字符串长度和匹配索引的不一致

Inconsistencies in caret position, string length and matches index in C#

我正在尝试使用 Regex 在 Scintilla 文本框中获取当前选定的单词,我注意到报告的字符串长度、匹配索引和插入符号位置或选择开始之间存在一些不一致:

private KeyValuePair<int, string> get_current_word()
{
    int cur_pos = scin_txt.Selection.Start;
    KeyValuePair<int, string> kvp_word = new KeyValuePair<int, string>(0, "");
    MatchCollection words = Regex.Matches(scin_txt.Text, @"\b(?<word>\w+)\b");
    foreach (Match word in words)
    {
        int start = word.Index;
        int end = start + word.Length;
        if (start <= cur_pos && cur_pos <= end)
        {
            kvp_word = new KeyValuePair<int,string>(start, word.Value);
            break;
        }
    }
    return kvp_word;
}

简而言之,我将字符串拆分为单词并使用匹配索引来查看插入符当前是否包含在单词中。

不幸的是,数字似乎没有正确匹配:

scin_txt 包含字符串:

"Le clic droit a été désactivé pour cette image. J"

这个字符串是49个字符长,但是TextLength属性returns53Selection.Start(或 Caret.Position,相同的结果)属性 returns 52。插入符号位于字符串的最后一个位置,并且(据我所知)在字母 "J".

之后没有空格或不可见字符

同时,Regex 匹配索引和长度似乎是正确的。

这是错误还是我不明白长度和选择索引的计算方式?是否有找到包含插入符的单词的解决方法?

Scintilla API 的命名很糟糕。 Text 属性 returns 字节,而不是文本,TextLength 给出字节数,而不是字符数。

据推测,您使用的是 UTF-8 模式,因此 "text" 实际上是:

Le clic droit a \xc3\xa9t\xc3\xa9 d\xc3\xa9sactiv\xc3\xa9 pour cette image. J

正好是 53 个字节长。

编辑:

如果你想找到一个词的 start/end 的位置,那么有 SCI_WORDSTARTPOSITION / SCI_WORDENDPOSITION messages. For caret positioning, there's the SCI_POSITIONBEFORE / SCI_POSITIONAFTER 消息,它考虑了当前的代码页。 (大概这些消息在您正在使用的特定 Scintilla 绑定的 API 中都有功能等价物 - 或者可能是一些用于访问它们的通用 SendMessage 函数)。