【发布时间】:2013-10-29 20:24:32
【问题描述】:
为新手问题道歉,但 C# 不是我的第一语言。
我正在尝试为给定内容中的单词之间的所有分隔符建立一个索引列表,并考虑标点符号。我希望使用正则表达式 \b (单词“边界”),但它与我没想到的各种东西相匹配。这是我写的方法:
internal static IList<int> GetBreakIndexesInContent(string content)
{
IList<int> indices = new List<int>();
if (content != null)
{
foreach (Match match in Regex.Matches(content, @"\b"))
{
Console.WriteLine("INDEX:[" + match.Index + "] CHAR:[" + content.Text[match.Index] + "] UNICODE:[" + (int)content.Text[match.Index] + "]");
indices.Add(match.Index);
}
}
return indices;
}
给定以下 100 个字符的字符串:
"Lorem ipsum dolor sit amet, tritani quaestio suscipiantur mea ea, duo et impedit facilisi evertitur."
我希望我的方法生成一个长度为 14 个元素的列表,其中第一个索引是位置 5,第二个位置是 11,依此类推(忽略位置 26 和 64 处的逗号,以及99)。相反,这是我得到的输出:
//COUNT: [30]
INDEX:[0] CHAR:[L] UNICODE:[76]
INDEX:[5] CHAR:[ ] UNICODE:[32]
INDEX:[6] CHAR:[i] UNICODE:[105]
INDEX:[11] CHAR:[ ] UNICODE:[32]
INDEX:[12] CHAR:[d] UNICODE:[100]
INDEX:[17] CHAR:[ ] UNICODE:[32]
INDEX:[18] CHAR:[s] UNICODE:[115]
INDEX:[21] CHAR:[ ] UNICODE:[32]
INDEX:[22] CHAR:[a] UNICODE:[97]
INDEX:[26] CHAR:[,] UNICODE:[44]
INDEX:[28] CHAR:[t] UNICODE:[116]
INDEX:[35] CHAR:[ ] UNICODE:[32]
INDEX:[36] CHAR:[q] UNICODE:[113]
INDEX:[44] CHAR:[ ] UNICODE:[32]
INDEX:[45] CHAR:[s] UNICODE:[115]
INDEX:[57] CHAR:[ ] UNICODE:[32]
INDEX:[58] CHAR:[m] UNICODE:[109]
INDEX:[61] CHAR:[ ] UNICODE:[32]
INDEX:[62] CHAR:[e] UNICODE:[101]
INDEX:[64] CHAR:[,] UNICODE:[44]
INDEX:[66] CHAR:[d] UNICODE:[100]
INDEX:[69] CHAR:[ ] UNICODE:[32]
INDEX:[70] CHAR:[e] UNICODE:[101]
INDEX:[72] CHAR:[ ] UNICODE:[32]
INDEX:[73] CHAR:[i] UNICODE:[105]
INDEX:[80] CHAR:[ ] UNICODE:[32]
INDEX:[81] CHAR:[f] UNICODE:[102]
INDEX:[89] CHAR:[ ] UNICODE:[32]
INDEX:[90] CHAR:[e] UNICODE:[101]
INDEX:[99] CHAR:[.] UNICODE:[46]
我之所以不简单地尝试匹配" " 或稍后只是过滤ASCII 32,是因为这需要对不一定在所有单词之间使用空格的外语保持敏感。另外,因为我不想无意中将多个空间捕获为单独的“分隔符”。
我真的希望\b 能成为真正的单词分离的一个很好的标准包罗万象,但似乎并非如此。我可以“自己动手”,但如果 C# 已经有某种工具来处理这个问题,我希望我可以省去重新发明轮子的麻烦。
当然,我们将不胜感激。
谢谢, 格雷格。
【问题讨论】:
-
\b是一种被称为 zero-width 转义序列的东西 --- 从技术上讲,它实际上不匹配任何 character ---但匹配所有,嗯...boundaries,这就是为什么您看到的结果比您预期的要多。试试\b(?<=[a-zA-Z])。这使用了一种称为肯定的后向断言的东西来断言边界之前的字符是一个字母。如果您不希望 spaces 成为这些边界的一部分,请尝试\b(?<=[a-zA-Z])(?!\s),它只是添加一个 negative lookahead assertion 来断言后面的字符边界不是空格。 -
阅读本文了解更多信息:regular-expressions.info/wordboundaries.html