我疯狂地试图让正则表达式检测用户输入中的关键字垃圾邮件。通常在开始时有一些普通文本,在结尾处有关键字垃圾邮件,用逗号或其他字符分隔。
我需要的是一个正则表达式,以计算关键字的数量来标记人类检查它的文本。
文字通常是这样的:
[random text, with commas, dots and all]
keyword1, keyword2, keyword3, keyword4, keyword5,
Keyword6, keyword7, keyword8...
我已经尝试了几个正则表达式来计算匹配:
- 这只会获得两个关键字中的一个
[,-](\w|\s)+[,-]
- 这也匹配随机文本
(?:([^,-]*)(?:[^,-]|$))
有谁能告诉我一个正则表达式吗?或者我应该采取不同的方法?
谢谢!
答案 0 :(得分:6)
回答我的问题,这是一个正则表达式,用于匹配两个逗号之间出现的字符串。
(?<=,)[^,]+(?=,)
此正则表达式与分隔逗号不匹配,因此不会消耗。 这个正则表达式在前一句中匹配“因此不消耗”。
你的正则表达式匹配并使用逗号这一事实是你尝试的正则表达式只匹配其他所有候选者的原因。
此外,如果整个输入是单个字符串,您将需要防止换行。在这种情况下,你会想要使用;
(?<=,)[^,\n]+(?=,)
答案 1 :(得分:2)
正如其他人所说,这可能是一个非常非常棘手的事情......它会遭受与一般“文字过滤”相同的所有失败(例如,人们将“屏蔽”输入) 。如果没有足够的示例帖子来测试它会变得更加困难......
无论如何,假设关键字与输入的其余部分分开,并用逗号分隔,您可以使用以下关键字匹配行:
#(?:^)((?:(?:[\w\.]+)(?:, ?|$))+)#m
取自上述问题:
[随机文字,逗号,圆点和所有]
keyword1,keyword2,keyword3,keyword4,keyword5,
关键字6,关键字7,关键字8
// preg_match_all('#(?:^)((?:(?:[\w]+)(?:, ?|$))+)#m', $string, $matches);
// var_dump($matches);
array(2) {
[0]=>
array(2) {
[0]=>
string(49) "keyword1, keyword2, keyword3, keyword4, keyword5,"
[1]=>
string(31) "Keyword6, keyword7, keyword8..."
}
[1]=>
array(2) {
[0]=>
string(49) "keyword1, keyword2, keyword3, keyword4, keyword5,"
[1]=>
string(31) "Keyword6, keyword7, keyword8"
}
}
#(?:^)((?:(?:[\w]+)(?:, ?|$))+)#m
#
=&gt;开始分隔符(?:^)
=&gt;匹配非捕获组中的行首(您可以使用^
我最初使用|\n
并且未更新)(
=&gt;启动捕获组(?:
=&gt;启动非捕获组(?:[\w]+)
=&gt;一个非捕获组,用于匹配一个或多个单词字符a-zA-Z0-9_
(使用字符类,以便在需要时添加到其中......)(?:, ?|$)
=&gt;非捕获组,用于匹配逗号(带有可选空格)或字符串/行的结尾)+
=&gt;结束非捕获组(4)并重复5/6以在行中找到多个匹配项)
=&gt;关闭捕获组3 #
=&gt;结束分隔符m
=&gt;多行修饰符从第2位跟进:
#^((?:(?:[\w]+)(?:, ?|$))+)#m
现在返回包含关键词的行数组,您可以计算逗号数量,从而获得关键字数量
$key_words = implode(', ', $matches[1]); // Join lines returned by preg_match_all
echo substr_count($key_words, ','); // 8
N.B。在大多数情况下,这将返回NUMBER_OF_KEY_WORDS - 1
(即在您的情况下为7);它返回8
,因为你的第一行关键词的末尾有一个逗号。
http://php.net/manual/en/reference.pcre.pattern.modifiers.php
http://www.regular-expressions.info/
http://php.net/substr_count
答案 2 :(得分:0)
为什么不直接使用爆炸和修剪?
$keywords = array_map ('trim', explode (',', $keywordstring));
然后对$ keywords执行count()。
如果您认为带有空格的关键字是垃圾邮件,那么您可以迭代$ keywords数组并查找包含空格的任何内容。可能有合理的理由在关键字中包含空格。例如,如果您在谈论系统中的超级英雄,有人可能会输入The Tick
或Iron Man
作为关键字
我不认为计算关键字和在关键字中查找空格是非常好的检测垃圾邮件的策略。您可能希望改为考虑其他机器人保护策略,甚至使用手动审核。
答案 3 :(得分:0)
我认为难点在于随机文本也可以包含逗号。
如果关键字全部在一行上并且它是整个文本的最后一行,请修剪整个文本,从末尾删除新行字符。然后从最后一个新行字符到结尾。这应该是包含关键字的字符串。一旦你将这个部分挑出来,你可以在逗号上爆炸字符串并计算部分。
<?php
$string = " some gibberish, some more gibberish, and random text
keyword1, keyword2, keyword3
";
$lastEOL = strrpos(trim($string), PHP_EOL);
$keywordLine = substr($string, $lastEOL);
$keywords = explode(',', $keywordLine);
echo "Number of keywords: " . count($keywords);
我知道这不是正则表达式,但我希望它有所帮助。
找到解决方案的唯一方法是找到将随机文本与关键字中不存在的关键字分开的内容。如果关键字中存在新行,则无法使用它。但是连续2个新线?或任何其他角色。
$string = " some gibberish, some more gibberish, and random text
keyword1, keyword2, keyword3,
keyword4, keyword5, keyword6,
keyword7, keyword8, keyword9
";
$lastEOL = strrpos(trim($string), PHP_EOL . PHP_EOL); // 2 end of lines after random text
$keywordLine = substr($string, $lastEOL);
$keywords = explode(',', $keywordLine);
echo "Number of keywords: " . count($keywords);
(编辑:添加更多新行的示例 - 远射)
答案 4 :(得分:0)
您的第一个正则表达式不需要前面的逗号
[\w\s]+[,-]
答案 5 :(得分:0)
如果人们在 2021 年仍然搜索此内容
([^,\n])+
匹配除新行和逗号以外的任何内容 regexr.com/60eme