【问题标题】:Regex - Match ( only ) words with mixed chars正则表达式 - 匹配(仅)具有混合字符的单词
【发布时间】:2009-05-10 19:08:29
【问题描述】:

我正在编写我的反垃圾邮件/恶意过滤器,如果可能的话,我需要,

仅匹配(检测)由混合字符组成的单词,例如:fr1&nd$ 而不是朋友

这可以用正则表达式吗!?

最好的问候!

【问题讨论】:

    标签: php regex filter match profanity


    【解决方案1】:

    当然可以使用正则表达式!你不是要求匹配嵌套的括号! :P

    但是,是的,正则表达式就是为此而构建的。一个例子:

    /\S*[^\w\s]+\S*/
    

    这将匹配以下所有内容:

    @ss
    as$
    a$s
    @$s
    a$$
    @s$
    @$$
    

    它会匹配这个:

    ass
    

    我相信这就是你想要的。它是如何工作的:

    \S* 匹配 0 个或多个非空格字符。 [^\w\s]+ 仅匹配符号(它将匹配任何不是单词或空格的内容),并匹配其中的 1 个或多个(因此需要符号字符。)然后 \S* 再次匹配 0 个或多个非-空格字符(符号和字母)。

    如果允许我提出更好的策略,在 Perl 中,您可以将正则表达式存储在变量中。我不知道你是否可以在 PHP 中做到这一点,但如果可以,你可以构造一个变量列表,如下所示:

    $a = /[aA@]/ # regex that matches all a-like symbols
    $b = /[bB]/
    $c = /[cC(]/
    # etc...
    

    或者:

    $regex = array( 'a' => /[aA@]/, 'b' => /[bB]/, 'c' => /[cC(]/, ... );
    

    这样,您可以将“朋友”的所有排列匹配:

    /$f$r$i$e$n$d/
    

    或者:

    /$regex['f']$regex['r']$regex['i']$regex['e']$regex['n']$regex['d']/
    

    当然,第二个看起来不必要地冗长,但那是你的 PHP。我认为第二个可能是最好的解决方案,因为它将它们全部存储在哈希中,而不是全部作为单独的变量,但我承认它产生的正则表达式有点难看。

    【讨论】:

    • 真棒正则表达式+解释+1!顺便说一句,PHP 中的正则表达式存储在字符串中,因此像您建议的那样进行变量排列当然是可能的。
    • 实际上,将其写入函数可能会很有趣。传入一个普通单词,它会用正确的正则表达式回复以检测该单词。我能看到的唯一问题是 W = \/\/ 或任何多字符。
    • W = !(?:[wW]|\\/\\/)! (在我的本地 Perl 中)。对于像 W 这样的具有多字符匹配的事情会更加困难,但肯定是可能的。可以很容易地编写一个函数,它逐个字符地遍历一个字符串,并查找一个正则表达式以匹配该字符,然后将它们全部组装成一个巨大的(看起来很可怕的)正则表达式,您可以使用它来匹配那个单词。但是,我不经常使用 PHP 来做到这一点。如果我一时兴起,我可能会在 Perl 中做到这一点。或者该表达式应该是什么。
    【解决方案2】:

    有可能,您不会有非常漂亮的正则表达式规则,但您基本上可以匹配您可以使用正则表达式描述的任何模式。棘手的部分是描述它。

    我猜你会有一堆正则表达式规则来检测像这样的坏词:

    要检测 fr1&nd$、friends、fr**nd*,您可以使用如下正则表达式:

    /fr[1iI*][&eE]nd[s$Sz]/

    对每条规则执行类似操作会在括号中找到所有可能字符的变体。获取正则表达式指南以获取更多信息。

    (我假设您需要friendfrie** 的坏词过滤器,您可能想要屏蔽坏词以及所有可能的排列)

    【讨论】:

    • 我觉得无聊,在 Perl 中做了一次。正则表达式看起来确实很可怕,尤其是当您尝试解释拼写错误时。
    【解决方案3】:

    没有彻底测试,但应该这样做:

    (\w+)*(?<=[^A-Za-z ])
    

    【讨论】:

    • 这匹配“a”(单词后跟空格)。
    • 我的错 :) 我已经改了,多余的空间应该可以做到。
    【解决方案4】:

    您可以构建一些正则表达式,如下所示:

    \p{L}+[\d\p{S}]+\S*
    

    这将匹配任何一个或多个字母(\p{L}+,参见Unicode character preferences)、一个或多个数字或符号([\d\p{S}]+)以及任何后续非空白字符\S*的序列。

    $str = 'fr1&nd$ and not friends';
    preg_match('/\p{L}+[\d\p{S}]+\S*/', $str, $match);
    var_dump($match);
    

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 2015-01-28
      • 2017-07-08
      • 2021-05-23
      • 1970-01-01
      相关资源
      最近更新 更多