将句子拆分为单词,但在C#中处理标点符号时遇到了困难。

15

我看到过一些类似的问题,但是我正在尝试实现以下目标。

给定一个字符串 str =“The moon is our natural satellite,即它围绕地球旋转!” 我想提取单词并将它们存储在一个数组中。 预期的数组元素应该是这样的。

the 
moon 
is 
our 
natural 
satellite 
i.e. 
it  
rotates 
around 
the 
earth

我曾经尝试使用String.split( ','\t','\r'),但这种方法并不能正确地工作。我还试图删除“.”和其他标点符号,但是我希望像"i.e."这样的字符串也被解析出来。有什么更好的方法可以解决此问题吗? 我也试过使用regex.split,但没有成功。
string[] words = Regex.Split(line, @"\W+");

我希望你能给我一些正确方向上的提示。涉及到IT技术相关内容,请让翻译更加通俗易懂,不需要解释,但请保留HTML标签。谢谢!


在“i.e.”中的第二个“.”和标点符号“.”是无法区分的,除非您添加一个已知以“.”结尾的单词列表。 - CodesInChaos
13
我注意到月球在自己的轴周围旋转。它绕地球公转 - Eric Lippert
4个回答

39

一个正则表达式的解决方案。

(\b[^\s]+\b)

如果您真的想要修复i.e.上最后一个 .,您可以使用以下方法。

((\b[^\s]+\b)((?<=\.\w).)?)

这是我正在使用的代码。

  var input = "The moon is our natural satellite, i.e. it rotates around the Earth!";
  var matches = Regex.Matches(input, @"((\b[^\s]+\b)((?<=\.\w).)?)");

  foreach(var match in matches)
  {
     Console.WriteLine(match);
  }
结果:
The
moon
is
our
natural
satellite
i.e.
it
rotates
around
the
Earth

但是这样不会把标点符号包括在单词中吗?所以在上面的例子中,最后一个单词将是“Earth!”... - Jim Mischel
1
不,它不会匹配地球上的标点符号。\b 只匹配单词边界。 - TheCodeKing
@Thecodeking,那么匹配“i.e.”呢?或者像“u.n.i.c.e.f”这样的东西? - Richard N
你是在使用Regex.Split吗? - Richard N
谢谢更新。我会把这个标记为答案。我会继续使用我现有的字符串分割方法,但是会将这个作为一个选项。显然,我需要更多地了解正则表达式。 - Richard N
显示剩余3条评论

9
我怀疑你所寻求的解决方案比你想象的要复杂得多。您正在寻找某种实际语言分析形式,或者至少是一个字典,以便您可以确定句号是否是单词的一部分还是结束句子的标志。你有没有考虑到它可能同时做两者?
考虑添加一个允许包含标点符号的“单词字典”。这可能是解决您问题最简单的方法。

正则表达式可以使用\b来实现这一点,这样你就不必担心了,尽管有些地方还是存在一些灰色区域。例如,i.e.将匹配为i.e - TheCodeKing

1

这对我有效。

var str="The moon is our natural satellite, i.e. it rotates around the Earth!";
var a = str.Split(new char[] {' ', '\t'});
for (int i=0; i < a.Length; i++)
{
    Console.WriteLine(" -{0}", a[i]);
}

结果:

 -The
 -moon
 -is
 -our
 -natural
 -satellite,
 -i.e.
 -it
 -rotates
 -around
 -the
 -Earth!

你可以对结果进行一些后处理,例如去除逗号和分号等。


这是否是最佳解决方案?对于这种情况,后期处理是否被认为是低效的? - Richard N

1
Regex.Matches(input, @"\b\w+\b").OfType<Match>().Select(m => m.Value)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接