我正在尝试使用 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
属性返回 53 且 Selection.Start
(或 Caret.Position
,相同的结果)属性返回 52。插入符号位于字符串的最后一个位置,并且(据我所知)字母“J”后面没有空格或不可见字符。
同时,正则表达式匹配索引和长度似乎是正确的。
这是一个错误还是我不明白长度和选择索引的计算方式?是否有解决方法可以找到包含插入符号的单词?
最佳答案
Scintilla API 的命名很糟糕。 Text
属性返回字节,而不是文本,TextLength
给出字节数,而不是字符数。
据推测,您使用的是 UTF-8 模式,因此“文本”实际上是:
Le clic droit a \xc3\xa9t\xc3\xa9 d\xc3\xa9sactiv\xc3\xa9 pour cette image. J
正好是 53 个字节长。
编辑:
如果你想找到一个单词的开始/结束位置,那么有 SCI_WORDSTARTPOSITION / SCI_WORDENDPOSITION消息。对于插入符定位,有 SCI_POSITIONBEFORE / SCI_POSITIONAFTER消息,考虑当前代码页。 (大概这些消息在您正在使用的特定 Scintilla 绑定(bind)的 API 中都有等效的功能 - 或者可能是一些用于访问它们的通用 SendMessage
函数)。
关于c# - C# 中插入符位置、字符串长度和匹配索引不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31053549/