我正在创建一个关键字黑名单,我想在文本文件中检查,但是,我找不到任何正则表达式文档,这将帮助我解决以下问题。
我有一组列入黑名单的关键字:
欢迎,再见,加入我们
我想查看一些文本文件以查找任何匹配项。我正在使用以下正则表达式来匹配确切的单词以及复数版本。
string.Format(@"\b{0}s*\b", keyword)
但是,我遇到了一个匹配关键字的问题,其中包含两个单词和两个单词之间的任何字符。上面的正则表达式匹配'加入我们',但我也需要匹配'join @ us'或'join_us'。
非常感谢任何帮助。
答案 0 :(得分:5)
我认为,“中间任何一个角色”可能会给你带来很多麻烦。例如,让我们考虑一下:
我们希望找到“我的精灵”......但你可能不想匹配“我自己”。
反正。如果您可以使用string.Replace
将空格字符替换为关键字中的点。
.
将匹配任何字符。
如果您不熟悉正则表达式,请查看此有用的备忘单:http://www.mikesdotnetting.com/article/46/c-regular-expressions-cheat-sheet
要解决“我自己”和“我的精灵”的问题,请在正则表达式中使用比.
更小心的东西。例如[^a-zA-Z]
将匹配除a到z和A到Z的字母之外的任何内容,或者\W
,它们将匹配非单词字符,这意味着除了a-zA-Z0-9_
之外的任何内容,所以它相当于[^a-zA-Z0-9_]
。
同样要注意城市 - 城市和所有不规则的复数形式。
答案 1 :(得分:0)
如果您开始使用复数,则必须使用PluralizationService
(有关详细信息,请参阅this answer。)
看到你正在使用string.Format
,我假设你正在循环你的后备列表数组。
那么为什么不用一个简洁的方法呢?
public static string GetBlacklistRegexString(string[] blacklist)
{
//It seems that this service only support engligh natively, to check later
var ps = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
//Using a StringBuilder for ease of use and performance,
//even though it's not easy on the eye :p
StringBuilder sb = new StringBuilder().Append(@"\b(");
//We're just going to make a unique regex with all the words
//and their plurals in a list, so we're looping here
foreach (var word in blacklist)
{
//Using a dot wasn't careful indeed... Feel free to replace
//"\W" with anything that does it for you. It will match
//any non-alphanumerical character
var regexPlural = ps.Pluralize(word).Replace(" ", @"\W");
var regexWord = word.Replace(" ", @"\W");
sb.Append(regexWord).Append('|').Append(regexPlural).Append('|');
}
sb.Remove(sb.Length - 1, 1); //removing the last '|'
sb.Append(@")\b");
return sb.ToString();
}
如果你已经在.NET中使用正则表达式,那么用法就不足为奇了:
static void Main(string[] args)
{
string[] blacklist = {"Goodbye","Welcome","join us"};
string input = "Welcome, come join us at dummywebsite.com for fun and games, goodbye!";
//I assume that you want it case insensitive
Regex blacklistRegex = new Regex(GetBlacklistRegexString(blacklist), RegexOptions.IgnoreCase);
foreach (Match match in blacklistRegex.Matches(input))
{
Console.WriteLine(match);
}
Console.ReadLine();
}
我们在控制台上写下了预期的输出:
编辑:仍然有问题(稍后再处理),如果你的关键字中有“男人”,那么它将与“女性”中的“男人”相匹配......奇怪的是我没有得到这种行为在regexhero。
编辑2:呃,当然如果我没有用括号分组单词,单词边界只应用于第一个和最后一个...更正。
答案 2 :(得分:0)
您可以尝试这样的事情(我只留下了正则表达式的{0}部分):
var relevantChars = new char[]{',', '@'}; // add here anything you like
string.Format(@"{0}", keyword.Replace(" ", "(" + string.Join("|", relevantChars ) + ")"));