繁体   English   中英

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

[英]Regex : how to get words from a string (C#)

我的输入由用户发布的字符串组成。

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

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

我需要的输出是列表:

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

我不是正则表达式的英雄,并且一直在谷歌搜索,但是我的Google功夫似乎很虚弱……

我将如何从输入转到所需的输出?

简单的正则表达式:

\\w+

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

这稍微更准确:

\\w(?<!\\d)[\\w'-]*

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

这是我的比赛:

1个LOLOLOL
2你已经
3个
4个PWN3D
5恩斯威
6陀螺

现在,更像是。

编辑:
令人反感的原因是某些正则表达式支持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]
[YOU'VE]
[BEEN]
[PWN3D]
[einszwei]
[drei]
[foo]
[bar]

我的直觉不是使用正则表达式,而只是执行一两个循环。

遍历字符串中的每个字符(如果不是有效的字符),将其替换为一个空格,然后使用String.Split()并拆分多个空格。

附签和连字符可能更难确定它们是否是垃圾字符或合法字符。 但是,如果您使用for循环遍历字符串,则从当前字符向后和向前看应该会有所帮助。

然后,您将看到一个单词列表-对于每个单词,请检查它们在词典中是否有效。 如果您希望这样做很快,那么最好执行某种二进制搜索。 但是,只要使其工作起来,线性搜索就会更容易开始。

编辑:我只提到字典的事情,因为我认为您可能只对合法的单词感兴趣,即不是“ asdfasdf”,但是如果那不是您所需要的,则忽略最后一条语句。

我为String编写了一个扩展,如下所示:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM