正则表达式:如何从字符串中获取单词(C#)

我的输入包含用户发布的字符串。

我想要做的是创建一个包含单词的字典,以及它们被使用的频率。 这意味着我想解析一个字符串,删除所有垃圾,并获得一个单词列表作为输出。

例如,假设输入是"#@!@LOLOLOL YOU'VE BEEN \***PWN3D*** ! :') !!!1einszwei drei !"

我需要的输出是列表:

  • "LOLOLOL"
  • "YOU'VE"
  • "BEEN"
  • "PWN3D"
  • "einszwei"
  • "drei"

我不是正则表达的英雄,一直在谷歌搜索,但我的谷歌功夫接缝是弱的……

我如何从输入转到想要的输出?

简单的正则表达式:

\w+

这匹配一串“单词”字符。 这几乎就是你想要的。

这稍微准确一些:

\w(?

它匹配任意数量的单词字符,确保第一个字符不是数字。

这是我的比赛:

1 LOLOLOL
2你
3 BEEN
4 PWN3D
5恩辛兹
6 drei

现在,这更像是它。

编辑:
负面后瞻的原因是一些正则表达式支持Unicode字符。 使用[a-zA-Z]会错过很多可取的“单词”字符。 允许\w和禁止\d包括可以想象在任何文本块中启动单词的所有Unicode字符。

编辑2:
我找到了一种更简洁的方法来获得负面的后观效果:双重负面字符类,只有一个负面排除。

[^\W\d][\w'-]*(?<=\w)

这与上面的相同,只是它还确保单词以单词字符结尾 。 最后,有:

[^\W\d](\w|[-']{1,2}(?=\w))*

确保一行中不超过两个非单词字符。 Aka,它匹配“word-up”而不是“word-up”,这是有道理的。 如果你想让它匹配“word-up”,而不是“word --- up”,你可以将2改为3

您应该研究自然语言处理(NLP),而不是正则表达式,如果您要定位多种口语,您还需要将其考虑在内。 由于您使用的是C#,请查看SharpNLP项目。

编辑 :只有在关心要分割的单词的语义内容时,才需要使用此方法。

如果您正在进行令牌化,那么您不一定需要正则表达式。 首先,您可以通过删除除空格之外的所有非字母字符来清理字符串,然后对空格字符执行Split() 。 这对大多数事情都有效,尽管收缩可能很困难。 这应该至少让你开始。

使用以下内容

 var pattern = new Regex( @"( [^\W_\d] # starting with a letter # followed by a run of either... ( [^\W_\d] | # more letters or [-'\d](?=[^\W_\d]) # ', -, or digit followed by a letter )* [^\W_\d] # and finishing with a letter )", RegexOptions.IgnorePatternWhitespace); var input = "#@!@LOLOLOL YOU'VE BEEN *PWN3D* ! :') !!!1einszwei drei foo--bar!"; foreach (Match m in pattern.Matches(input)) Console.WriteLine("[{0}]", m.Groups[1].Value); 

产生的产量

  [LOLOLOL]
 [你]
 [是]
 [PWN3D]
 [einszwei]
 [DREI]
 [富]
 [酒吧] 

我的直觉不是使用正则表达式,而只是做一两圈。

迭代字符串中的每个字符,如果不是有效字符,则用空格替换它然后使用String.Split()并拆分空格。

如果确定它们是垃圾字符还是合法字符,那么相似和连字符可能会更棘手。 但是如果你使用for循环遍历字符串,那么从当前字符向后和向前查看应该对你有所帮助。

然后你会得到一个单词列表 – 对于每个单词,检查它们是否在你的字典中有效。 如果你想要快速,那么执行某些二进制搜索将是最好的。 但只是为了使其工作线性搜索将更容易开始。

编辑:我只提到字典的事情,因为我认为你可能只对合法的词感兴趣,即不是“asdfasdf”但忽略了最后的陈述,如果那不是你需要的。

我写了一个String的扩展名,如下所示:

  private static string[] GetWords(string text) { List lstreturn = new List(); List lst = text.Split(new[] { ' ' }).ToList(); foreach (string str in lst) { if (str.Trim() == "") { lstreturn.Add(str); } } return lstreturn.ToArray(); }