[英]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.