我想,以取代在方括号中的所有字符串( []
从该的命名该字符串数组与随机选择的项目)。
这是非常相似的这个问题 ,但与一捻,因为我想从数组字符串命名的更换不同的支架的内容。
一个例子应该使这个更清楚一点。
所以说,我已经得到了串
"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
。 现在,如果随机选择它结束了重复的选择也没关系,但必须为每个新选择[]
项目。
我希望我已经解释清楚这一点。 如果你得到我想要达到并能想到更好的办法来做到这一点,我会非常感激。
算法
- 符合此正则表达式:
(\[.*?\])
- 对于每个匹配组从相关阵列选择一个项目。
- 借于字符串替换。
履行
$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函数执行正则表达式搜索,并使用提供的回调函数代替。
下面的代码将做的工作:
$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].";
输出之一如下所示,显示出我们跑出去可能会替换:
这是一个非常大的房子,这是一个大房子。 这也是小有。
这样做的(不是我的解决方案)的另一个好(容易)方法
https://stackoverflow.com/a/15773754/2183699
使用foreach来检查要替换哪些变量,并用它们替换
str_replace();
您可以使用的preg_match和str_replace函数功能来实现这一目标的目标。
- 首先找到使用的preg_match功能的匹配,然后创建搜索和从结果替换阵列。
- 通过将前一个数组作为参数调用str_replace函数的功能。
这是我的小更新来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;