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

本文关键字:不一致 索引 字符串 插入 符号 位置 | 更新日期: 2023-09-27 17:59:55

我正试图使用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_text包含字符串:

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

此字符串有49个字符长,但TextLength属性返回53并且Selection.Start(或Caret.Position,结果相同)属性返回52。插入符号位于字符串的最后一个位置,(据我所知)字母"J"后面没有空格或不可见字符。

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

这是一个错误,还是我不了解长度和选择索引的计算方式?是否有找到包含插入符号的单词的变通方法?

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

Scintilla API的名称不正确。Text属性返回字节,而不是文本,TextLength给出的是字节数,而不是字符数。

据推测,您使用的是UTF-8模式,因此"文本"是准确的:

这是一张图片。J

它正好是53字节长。

编辑

如果你想找到单词的起始/结束位置,那么就会有SCI_WORDSTARTPOSITION/SIC_WORDENDPOSITION消息。对于插入符号定位,有SCI_POSITIONBEFORE/SCI_POStatiONAFTER消息,它们考虑了当前代码页。(假设这些消息在您正在使用的特定Scintilla绑定的API中都具有功能等价物,或者可能是用于访问它们的某种通用SendMessage函数)。