括号内用PHP这样命名的变量替换文本(Replace text within brackets wi

2019-06-26 20:26发布

我想,以取代在方括号中的所有字符串( []从该的命名该字符串数组与随机选择的项目)。

这是非常相似的这个问题 ,但与一捻,因为我想从数组字符串命名的更换不同的支架的内容。

一个例子应该使这个更清楚一点。

所以说,我已经得到了串

"This is a very [adjective] [noun], and this is a [adjective] [noun]."

和变量:

$adjective = array("big","small","good","bad");
$noun      = array("house","dog","car");

我们希望它返回"This is a very big house, and this is a good dog." 或什么的,通过随机选择。 也就是说,我想要写一个PHP函数,将取代每个[string]从阵列名为随机选择项目$string 。 现在,如果随机选择它结束了重复的选择也没关系,但必须为每个新选择[]项目。

我希望我已经解释清楚这一点。 如果你得到我想要达到并能想到更好的办法来做到这一点,我会非常感激。

Answer 1:

算法

  1. 符合此正则表达式: (\[.*?\])
  2. 对于每个匹配组从相关阵列选择一个项目。
  3. 借于字符串替换。

履行

$string    = "This is a very [adjective] [noun], and this is a [adjective] [noun].";
$adjective = array("big","small","good","bad");
$noun      = array("house","dog","car");

// find matches against the regex and replaces them the callback function.
$result    = preg_replace_callback(

                 // Matches parts to be replaced: '[adjective]', '[noun]'
                 '/(\[.*?\])/',

                 // Callback function. Use 'use()' or define arrays as 'global'
                 function($matches) use ($adjective, $noun) {

                     // Remove square brackets from the match
                     // then use it as variable name
                     $array = ${trim($matches[1],"[]")};

                     // Pick an item from the related array whichever.
                     return $array[array_rand($array)];
                 },

                 // Input string to search in.
                 $string
             );

print $result;

说明

preg_replace_callback函数执行正则表达式搜索,并使用提供的回调函数代替。

  • 第一个参数是正则表达式匹配(斜线之间封入): /(\[.*?\])/

  • 第二个参数是回调函数来调用每场比赛。 注意到当前匹配的参数。

    • 我们必须使用use()在这里从函数内部访问阵列,或定义数组作为全球: global $adjective = ... 。 也就是说,我们必须做下列条件之一:

      一)定义数组作为global

          ...    全球$形容词=阵列( “大”, “小”, “好”, “坏”);    全球$名词=阵列( “房子”, “狗”, “汽车”);    ...    功能($匹配){    ... 

      b)利用use

          ...    $形容词=阵列( “大”, “小”, “好”, “坏”);    $名词=阵列( “家”, “狗”, “汽车”);    ...    功能($匹配)使用($形容词,名词$){    ... 
    • 回调函数的第一行:

      • 修剪 :删除方括号( []使用来自匹配) trim功能。

      • $ {}:创建一个变量来作为阵列名称与匹配名称中使用。 例如,如果$match[noun]然后trim($matches[1],"[]")返回noun (不带括号)和${noun}成为阵列名: $noun 。 有关主题的更多信息,请参阅变量变量

    • 第二线随机地挑选可用于索引号$array ,然后在该位置返回元素。

  • 第三个参数是输入字符串。



Answer 2:

下面的代码将做的工作:

$string = "This is a very [adjective] [noun], and this is a [adjective] [noun]."

function replace_word ( $matches )
{
    $replaces = array(
        '[adjective]'  =>  array("big", "small", "good", "bad"),
        '[noun]'  =>  array("house", "dog", "car")
    );

    return $replaces[$matches[0]][array_rand($replaces[ $matches[0] ])];
}

echo preg_replace_callback("(\[.*?\])", "replace_word", $string);

首先,我们对正则表达式匹配[something]字的部分,并调用replace_word()与它的回调函数preg_replace_callback() 此函数具有内部$replaces内部限定二维阵列深,在限定的每一行[word type] => array('rep1', 'rep2', ...)的格式。

棘手的和一个位线混淆是return $replaces[$matches[0]][array_rand($replaces[ $matches[0] ])]; 。 如果我大块下来了一点,这将是为您提供了更多可解析:

$random = array_rand( $replaces[ $matches[0] ] );

$matches[0]这个词的类型,这是在关键$replaces数组,我们正在寻找。 这是通过原始字符串的正则表达式中。 array_rand()基本上选择阵列中的一个元件,并返回它的数值指标 。 这样$random现在是整数介于0(number of elements - 1)含有替换阵列。

return $replaces[ $matches[0] ][$random];

这将返回$random从更换阵列个元素。 在代码中,这两条线拼凑成一条线。

显示一个元素只有一次

如果你想间断元素(没有两个形容词或名词重复两次),那么你需要做的另一个伎俩。 我们将设置$replaces阵列被里面没有定义replace_word()函数,但外界。

$GLOBALS['replaces'] = array(
    '[adjective]'  =>  array("big", "small", "good", "bad"),
    '[noun]'  =>  array("house", "dog", "car")
);

在函数内部中,我们将设置本地$replaces的变量设置为新设定的数组的引用,与主叫$replaces = &$GLOBALS['replaces']; 。 (在&运营商设置一个引用 ,所以我们有做的一切$replaces (删除和添加元素,例如)修改原始阵列了。没有它,就只能是复印件)。

而到达在之前return线,我们称之为unset()在当前待返回键。

unset($replaces[$matches[0]][array_rand($replaces[ $matches[0] ])]);

现在放在一起的功能如下:

function replace_word ( $matches )
{
    $replaces = &$GLOBALS['replaces'];
    unset($replaces[$matches[0]][array_rand($replaces[ $matches[0] ])]);

    return $replaces[$matches[0]][array_rand($replaces[ $matches[0] ])];
}

而且因为$replaces是全球参考, unset()也更新了原有的阵列。 下一次调用replace_word()将无法找到同样的再次更换。

小心数组的大小!

含多个字符串替换变量比的量的替代本将抛出未定义索引E_NOTICE 。 以下字符串将无法正常工作:

$string = "This is a very [adjective] [noun], and this is a [adjective] [noun]. This is also an [adjective] [noun] with an [adjective] [noun].";

输出之一如下所示,显示出我们跑出去可能会替换:

这是一个非常大的房子,这是一个大房子。 这也是小有。



Answer 3:

这样做的(不是我的解决方案)的另一个好(容易)方法

https://stackoverflow.com/a/15773754/2183699

使用foreach来检查要替换哪些变量,并用它们替换

str_replace();


Answer 4:

您可以使用的preg_match和str_replace函数功能来实现这一目标的目标。

  • 首先找到使用的preg_match功能的匹配,然后创建搜索和从结果替换阵列。
  • 通过将前一个数组作为参数调用str_replace函数的功能。


Answer 5:

这是我的小更新来mmdemirbas的回答以上。 它可以让你设置的功能以外的变量(即使用全局变量,因为说的)。

$result    = preg_replace_callback(

                 // Matches parts to be replaced: '[adjective]', '[noun]'
                 '/(\[.*?\])/',

                 // Callback function. Use 'use()' or define arrays as 'global'
                 function($matches) use ($adjective, $noun) {

                     // Remove square brackets from the match
                     // then use it as variable name
                    $arrayname = trim($matches[1],"[]");
                    $array = $GLOBALS[$arrayname];

                     // Pick an item from the related array whichever.
                     return $array[array_rand($array)];
                 },

                 // Input string to search in.
                 $string
             );

print $result;


文章来源: Replace text within brackets with thus-named variable in PHP