正规新手在这里。我正在尝试修复的论坛软件有一个(损坏的)插件。它产生了以下正则表达式:
/(?:\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" /> ';
}
// 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" /> ';
}
答案 0 :(得分:1)
这个(简化的)正则表达式应该替换[:)]和[;)]的每个实例:
(?:\[[:;]\)\])
答案 1 :(得分:0)
盲目猜测,因为没有代码和一些测试用例我无法确定:
该正则表达式仅捕获[:)]
和[;)]
的实例,这些实例被空格包围,或者位于字符串的开头或结尾。这就是(?:\s|^)
和(?:\s|$)
的含义。它可能与设计不匹配Hello[:)]World
。这是你正在测试它的情况吗?
编辑:知道了。由于正则表达式的编写方式,通过测试任一侧的空格,它包括匹配中的那些空格。那些比赛不能重叠。如果你要用两个空格分隔它们,你会看到预期的行为。
如果你不关心它没有反对言语,你的正则表达式的工作极其简化:逃避表情符号,然后用|
加入它们,以产生/\[\:\)\]|\[\;\)\]/
。
这可能是一次使用str_replace
几次的好地方。