简体   繁体   English

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

[英]replace text between strings in php

I need to find all instances of a two strings and replace all the text enclosed between them. 我需要找到两个字符串的所有实例,并替换它们之间包含的所有文本。 Eg: 例如:

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

Needs to be replaced with: 需要替换为:

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

So far I have the following which is working: 到目前为止,我有以下工作:

    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;

However, it replaces [NAME] in all the other custom tags I am using, for example I also have: 但是,它在我正在使用的所有其他自定义标签中替换了[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;

As you can see [FILE] uses target="_blank" and [LINK] uses target="_self", when I use the above script it replaces all instances of [NAME] to "_blank". 如您所见,[FILE]使用target =“ _ blank”,[LINK]使用target =“ _ self”,当我使用上述脚本时,它将[NAME]的所有实例替换为“ _blank”。

Renaming the tag [NAME] isn't a viable option as there are 1000's of entries already using it in the database and the users are accustomed to using it as is. 重命名[NAME]标签不是一个可行的选择,因为数据库中已有1000多个条目正在使用它,并且用户习惯于按原样使用它。

Is there a simple method to get this working? 有一种简单的方法可以使它正常工作吗?

$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);

This will only return if the entire pattern is matched: 仅在匹配整个模式时才返回:

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

First of all it is working by using a pattern which matches the whole thing, not just parts of the link. 首先,它通过使用匹配整个对象而不只是链接的一部分的模式来工作。

Here is a walkthrough of the regular expression (not a literal step by step of how a regular expression engine works before you regex nerds complain): 以下是正则表达式的演练(不是您正则表达式抱怨之前正则表达式引擎如何逐步执行的文字说明):

  1. Forward slashes are used to contain the expression. 正斜杠用于包含表达式。
  2. We put \\ before the [ to escape it, otherwise it is interpreted as the start of a character class. 我们将\\放在[之前,以对其进行转义,否则它将被解释为字符类的开始。
  3. We match the literal LINK] . 我们匹配文字LINK]
  4. We create a capturing group for any character . 我们为任何角色创建一个捕获组. , any number of times * , but with a lazy modifier ? ,多少次* ,但带有惰性修饰符? . This is back referenced by the $1 in the replacement string. $1在替换字符串中被反向引用。
  5. I won't explain the rest because it is the same process for the rest of the string. 我不会解释其余的部分,因为其余部分的处理过程相同。

Here is a PHPUnit class which demonstrates the correct behaviour: 这是一个演示正确行为的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);
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM