0

我找不到匹配重复字母的正则表达式。我的问题是我想使用正则表达式来过滤垃圾邮件,例如,我想使用正则表达式来检测这些字符串中的“垃圾邮件”和“伟哥”:“xxxSpAmyyy”、“xxxSPAMyyy”、“xxxvI a Gr AA” yyy", "xxxV iiA gR a xxx"

您对我如何以一种好的方式做到这一点有什么建议吗?

4

5 回答 5

0

喜欢搜索这个?

"v.{0,3}i.{0,3}a.{0,3}g.{0,3}r.{0,3}a"

模式


代码:

这会在字符之间留出 0 到 3 个字符的空间。我没有编译以下内容,但它“应该可以工作”。

String[] strings = new String[] { ""xxxV iiA gR a xxx"" };
final Pattern spamPattern = makePattern("viagra");
for (String s : strings) {
    boolean isSpam = spamPattern.matcher(s).find();
    if (isSpam) {
        System.out.println("Spam: " + s);
    }
}
...
Pattern makePattern(String cusWord) {
    cusWord = cusWord.toLowerCase();
    StringBuilder sb = new StringBuilder();
    sb.append("(?i)"); // Case-insensitive setting.
    for (int i = 0; i < cusWord.length(); ) {
        int cp = cusWord.codePointAt(i);
        i += Character.charCount(cp);
        if ('o' == cp) {
            sb.append("[o0]");
        } else if ('l' == cp) {
            sb.append("[l1]");
        } else {
            sb.appendCodePoint(cp);
        }
        sb.append(".{0,3}"); // 0 - 3 occurrences of any char.
    }
    return Pattern.compile(sb.toString());
}
于 2012-12-03T00:36:54.677 回答
0

这忽略了这种情况,无论它们是一个相邻的,还是它们之间有其他字符,都需要它们

"(?i).{0,}v.{0,}i.{0,}a.{0,}g.{0,}r.{0,}a.{0,}"

如果您知道字母之间可以有多少个字符,则可以输入.{0,max_distance}而不是.{0,}

更新:

它甚至适用于重复,因为我已经尝试过了:

    String str = "xxxV iiA gR a xxx";

    if(str.matches("(?i).{0,}v.{0,}i.{0,}a.{0,}g.{0,}r.{0,}a.{0,}")){
        System.out.println("Yes");
    }
    else{
        System.out.println("No");
    }

这打印Yes

于 2012-12-03T00:40:03.980 回答
0

我想,你走错路了。垃圾邮件的过滤与机器学习密切相关。我建议您阅读有关贝叶斯垃圾邮件过滤的信息。

如果您认为,您会收到带有拼写错误的单词(和其他类型的垃圾)的垃圾邮件 - 我建议您不要使用基于整个单词的过滤,而是基于n-grams

于 2012-12-03T00:44:25.053 回答
0

您可以尝试使用积极的前瞻

(?=.*v)(?=.*i)(?=.*a)(?=.*g)(?=.*r)(?=.*a).*

编辑:

(?=.*v.*i.*a.*g.*r.*a.*).*
于 2012-12-03T10:42:59.187 回答
0

你试过任何正则表达式吗?

\w*[sSpPaAmM]+\w*这样的东西应该可以解决问题

您可以在此站点上测试您的 RE:http ://www.regexplanet.com/advanced/java/index.html

于 2012-12-03T00:50:54.120 回答