在php中替换字符串之间的文本

时间:2016-01-22 20:08:37

标签: php string replace str-replace between

我需要找到两个字符串的所有实例并替换它们之间的所有文本。 E.g:

[LINK]mySite.com[NAME]Click to visit my site[ENDLINK]

需要替换为:

<a href="mySite.com">Click to visit my site</a>

到目前为止,我有以下工作:

    if(stristr("$text","[LINK]") && stristr("$text","[ENDLINK]")):
        $text = str_ireplace("[LINK]","\n<a href=\"" ,"$text");
        $text = str_ireplace("[NAME]", "\" target=\"_self\"><u>", "$text");
        $text = str_ireplace("[ENDLINK]","</u></a>","$text");
    endif;

但是,它取代了我正在使用的所有其他自定义标签中的[NAME],例如我也有:

   if(stristr("$text","[FILE]") && stristr("$text","[ENDFILE]")):
        $text = str_ireplace("[FILE]","\n<a href=\"" ,"$text");
        $text = str_ireplace("[NAME]", "\" target=\"_blank\"><u>", "$text");
        $text = str_ireplace("[ENDFILE]","</u></a>","$text");
    endif;

正如您所见[FILE]使用target =&#34; _blank&#34;并且[LINK]使用target =&#34; _self&#34;,当我使用上面的脚本时,它将[NAME]的所有实例替换为&#34; _blank&#34;。

重命名标签[NAME]并不是一个可行的选项,因为已有1000个条目已在数据库中使用它,并且用户习惯按原样使用它。

是否有一种简单的方法可以使其正常工作?

2 个答案:

答案 0 :(得分:0)

$text = "[LINK]picture-large.jpg[NAME][IMAGE]picture-small.jpg[ENDIMAGE][ENDLINK] ... [LINK]mySite.com[NAME]Click to visit my site[endlink] lorem ipsum dolor sit amet ... [LINK]anothersite.com[name]Don't click here[ENDLINK] and here goes the file: [FILE]file.pdf[NAME]This is link to file[ENDFILE]";

function replaceFiles($match) {
    return '<a href="'.$match[1].'" target="_blank"><u>'.$match[2].'</u></a>';
}

function replaceImages($match) {
    return '<img src="'.$match[1].'" />';
}

function replaceLinks($match) {
    return '<a href="'.$match[1].'" target="_self"><u>'.$match[2].'</u></a>';
}


$text = preg_replace_callback('/\[FILE\](.*?)\[NAME\](.*?)\[ENDFILE\]/i', 'replaceFiles', $text);
$text = preg_replace_callback('/\[IMAGE\](.*?)\[ENDIMAGE\]/i', 'replaceImages', $text);
$text = preg_replace_callback('/\[LINK\](.*?)\[NAME\](.*?)\[ENDLINK\]/i', 'replaceLinks', $text);

答案 1 :(得分:0)

只有在整个模式匹配时才会返回:

public function replaceLinks($text){
    return preg_replace('/\[LINK](.*?)\[NAME](.*?)\[ENDLINK]/', "<a href='$1'>$2</a>", $text);
}

首先,它通过使用匹配整个事物的模式来工作,而不仅仅是链接的一部分。

这是正则表达式的演练(不是正则表达式引擎在你正则表达式抱怨之前如何正常工作的文字):

  1. 正斜杠用于包含表达式。
  2. 我们将\放在[之前以逃避它,否则它被解释为字符类的开头。
  3. 我们匹配文字LINK]
  4. 我们为任何字符.创建一个捕获组,任意次*,但使用延迟修饰符?。这由替换字符串中的$1反向引用。
  5. 我不会解释其余部分,因为它与字符串的其余部分是相同的过程。
  6. 这是一个演示正确行为的PHPUnit类:

    class Test extends PHPUnit_Framework_TestCase {
    
      public function replaceLinks($text){
        return preg_replace('/\[LINK](.*?)\[NAME](.*?)\[ENDLINK]/', "<a href='$1'>$2</a>", $text);
      }
    
      public function testCase1(){
    
        // Must replace links
        $input = "[LINK]mySite.com[NAME]Click to visit my site[ENDLINK]";
        $output = $this->replaceLinks($input);
        $expected = "<a href='mySite.com'>Click to visit my site</a>";
        $this->assertEquals($expected, $output);
    
      }
    
      public function testCase2(){
    
        // Must not replace files 
        $input = "[FILE]mySite.com[NAME]Click to visit my site[ENDFILE]";
        $output = $this->replaceLinks($input);
        $expected = "[FILE]mySite.com[NAME]Click to visit my site[ENDFILE]";
        $this->assertEquals($expected, $output);
      }
    
    }