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

Posted

技术标签:

【中文标题】C# 中插入符号位置、字符串长度和匹配索引的不一致【英文标题】:Inconsistencies in caret position, string length and matches index in C# 【发布时间】:2015-06-25 14:41:21 【问题描述】:

我正在尝试使用正则表达式在 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 属性返回 53 并且 Selection.Start(或 Caret.Position,相同结果)属性返回 52。插入符号位于字符串的最后一个位置,并且(据我所知)字母“J”之后没有空格或不可见字符。

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

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

【问题讨论】:

【参考方案1】:

Scintilla API 命名不当。 Text 属性返回字节,而不是文本,TextLength 给出字节数,而不是字符数。

大概,你使用的是UTF-8模式,所以“文本”实际上是:

Le clic droit 一个 \xc3\xa9t\xc3\xa9 d\xc3\xa9sactiv\xc3\xa9 倒 cette 图像。 J

正好是 53 字节长。

编辑

如果你想找到一个单词的开始/结束的位置,那么有SCI_WORDSTARTPOSITION / SCI_WORDENDPOSITION 消息。对于插入符号定位,有 SCI_POSITIONBEFORE / SCI_POSITIONAFTER 消息,它考虑了当前代码页。 (大概这些消息在您正在使用的特定 Scintilla 绑定的 API 中都有等效的功能 - 或者可能是一些通用的 SendMessage 函数来访问它们)。

【讨论】:

啊,这就解释了。我虽然有类似的想法,但我认为文本是 Unicode,而不是 UTF8,结果没有意义。有没有一种简单的方法可以知道插入符号在字符串中的位置,或者有另一种方法可以知道当前单词是什么? @Sylverdrag。不确定是否简单,但请参阅我的一些选项的更新答案。 谢谢。事实证明它在 .NET 中非常简单。我找到了一个将位置转换为文本位置的“.GetColumn(int)”方法。

以上是关于C# 中插入符号位置、字符串长度和匹配索引的不一致的主要内容,如果未能解决你的问题,请参考以下文章

c# 怎样获取string的某个字符最后一位的位置!

MySQL InnoDB引擎索引长度受限怎么办

C中溢出后有符号和无符号的不一致相等

Linux系统学习之正则表达式

Sql Server中通配符

转载C#中string类使用Remove方法来移除指定位置的字符