簡體   English   中英

無法弄清楚此正則表達式有什么問題

[英]Can't figure out what's wrong with this regex

正則表達式新手在這里。 我正在嘗試修復的論壇軟件有一個(損壞的)插件。 它生成以下正則表達式:

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

...使用preg_replace()替換文本塊中[:)][;)]所有實例。 但是,它不會替換[:)][;)]的實例。 有任何想法嗎?

編輯:有問題的插件是Emoticons ,適用於Vanilla。 這是代碼(不相關的部分和電子郵件地址已刪除):

 // 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|^)(?:\\s|$)意思。 它可能與Hello[:)]World不匹配,可能是設計使然。 您是否正在測試這種情況?

編輯:知道了。 由於正則表達式的編寫方式,因此通過測試兩側的空格,它將正則表達式中的空格包括在內。 那些比賽不能重疊。 如果將它們用兩個空格分開,則會看到預期的行為。

如果您不在乎它不會碰到單詞,那么使用該正則表達式的工作將大大簡化:轉義表情符號,然后使用| ,以產生/\\[\\:\\)\\]|\\[\\;\\)\\]/

不過,這可能是只使用str_replace幾次的更好的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM