English 中文(简体)
弄不清这个正则表达式出了什么问题
原标题:Can t figure out what s wrong with this regex
  • 时间:2010-10-09 21:25:51
  •  标签:
  • php
  • regex

Regex新手来了。我正在尝试修复论坛软件的一个插件(坏了)。它正在生成以下正则表达式:

/(?:s|^)[(?::)]|;)])(?:s|$)/m

…使用preg_replace()替换文本块中[:)][];)]的所有实例。但是,它并没有取代[:)][;)]的实例。有什么想法吗?

编辑:有问题的插件是表情符号,代表香草。以下是代码(删除了无关部分和电子邮件地址):

    // Build an Array containing the Emoticon<-->Graphic matches
    if (!isset($EmoticonMatch))
    {
        $EmoticonMatch = array(
             [:)]   =>  smile.gif ,
             [;)]   =>  wink.gif ,
        ); // Add more matches, if you need them... Put the corresponding graphics into the Plugin s images-folder
    }

    // In case there s something wrong with the Array, exit the Function
    if (count($EmoticonMatch) == 0)
        return;

    // Define the basic Regex pattern to find Emoticons
    $EmoticonsSearch =  /(?:s|^) ;

    // Automatically extend the Regex pattern based on the Emoticon-Codes in the $EmoticonMatch-Array
    $subchar =   ;
    foreach ( (array) $EmoticonMatch as $Smiley => $Img ) {
        $firstchar = substr($Smiley, 0, 1);
        $rest = substr($Smiley, 1);

        // new subpattern?
        if ($firstchar != $subchar) {
            if ($subchar !=   ) {
                $EmoticonsSearch .=  )|(?:s|^) ;
            }
            $subchar = $firstchar;
            $EmoticonsSearch .= preg_quote($firstchar,  / ) .  (?: ;
        } else {
            $EmoticonsSearch .=  | ;
        }
        $EmoticonsSearch .= preg_quote($rest,  / );
    }

    // Add final Regex pattern to the Search-Variable
    $EmoticonsSearch .=  )(?:s|$)/m ;

}


/**
 * Hack the Discussion-Controller to replace Text with Smilies before output
 * 
 * @since 1.0
 * @version 1.0
 * @author Oliver Raduner
 *
 * @uses Initialize()
 * @uses FindEmoticon()
 */
public function DiscussionController_BeforeCommentDisplay_Handler(&$Sender)
{
    // Get the current Discussion and Comments
    $Discussion = &$Sender->EventArguments[ Discussion ];
    $Comment = &$Sender->EventArguments[ Comment ];

    // Initialize the our Emoticons-Stuff
    $this->Initialize();

    // Replace Emoticons in the Discussion and all Comments to it
    $Discussion->Body = $this->FindEmoticon($Discussion->Body);
    $Comment->Body = $this->FindEmoticon($Comment->Body);
}


/**
 * Search through a Text and find any occurence of an Emoticon
 *
 * @since 1.0
 * @version 1.0
 * @author Oliver Raduner
 *
 * @uses $EmoticonImgTag()
 * @global array $EmoticonsSearch()
 * @param string $Text Content to convert Emoticons from.
 * @return string Converted string with text emoticons replaced by <img>-tag.
 */
public function FindEmoticon($Text)
{
    global $EmoticonsSearch;

    $Output =   ;
    $Content =   ;

    // Check if the Emoticons-Searchstring has been set properly
    if (!empty($EmoticonsSearch) )
    {
        $TextArr = preg_split("/(<.*>)/U", $Text, -1, PREG_SPLIT_DELIM_CAPTURE); // Capture the Tags as well as in between
        $Stop = count($TextArr);

        for ($i = 0; $i < $Stop; $i++)
        {
            $Content = $TextArr[$i];

            // Check if it s not a HTML-Tag
            if ((strlen($Content) > 0) && ( <  != $Content{0}))
            {
                // Documentation about preg_replace_callback: http://php.net/manual/en/function.preg-replace-callback.php
                $Content = preg_replace_callback($EmoticonsSearch, array(&$this,  EmoticonImgTag ), $Content);
            }

            $Output .= $Content;
        }

    } else {
        // Return default text.
        $Output = $Text;
    }

    return $Output;
}


/**
 * Translate an Emoticon Code into a <img> HTML-tag
 * 
 * @since 1.0
 * @version 1.0
 * @author Oliver Raduner
 * 
 * @global array $EmoticonMatch
 * @param string $Emoticon The Emoticon Code to convert to image.
 * @return string HTML-Image-Tag string for the emoticon.
 */
public function EmoticonImgTag($Emoticon)
{
    global $EmoticonMatch;

    $PluginRoot =  Gdn::Config( Garden.WebRoot ).  plugins  . DS .  Emoticons  . DS;

    if (count($Emoticon) == 0) {
        return   ;
    }

    $Emoticon = trim(reset($Emoticon));
    $Img = $EmoticonMatch[$Emoticon];
    $EmoticonMasked = $Emoticon;

    return   <img src=" .$PluginRoot. images .DS.$Img. " alt=" .$EmoticonMasked. " class="emoticon" />  ;
}

>

最佳回答

盲目猜测,因为如果没有代码和一些测试用例,我无法确定:

该正则表达式只捕获[:)][];)]的实例,这些实例要么被空白包围,要么位于字符串的开头或结尾。这就是(?:s|^)的意思。它将不匹配<code>Hello〔:)〕World</code>,可能是设计的。这就是你正在测试的那种情况吗?

EDIT:明白了。由于正则表达式是如何编写的,通过测试两边的空格,它将这些空格包括在匹配中。那些匹配不能重叠。如果你用两个空格将它们分开,你会看到预期的行为。

如果你不在乎它不会遇到单词,那么你使用正则表达式的工作就非常简单了:转义表情符号,然后将它们与|连接,生成/[:)]|[;)]/

不过,这可能是一个只使用str_replace几次的更好地方。

问题回答

这个(简化的)正则表达式应该替换[:)]和[;)]的每个实例:

(?:[[:;])])




相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...