0

我有一个字符串,其中包含纯文本“[var-X]”的各种实例,其中 X 可以是任何正整数。我不知道在任何给定脚本中 X 可以达到多高(但是如果需要,我可以得到它)。

这些 [var-X] 中的每一个都必须由不同的字符串进行评估和替换。不同字符串的值取决于我解析没有问题的外部 xml 文件。

所以,我的问题是,我该如何从

$str = "Hey I am some text,[var-1] a lot of these [var-3] parts will have to [var-9] go away and
be exchanged [var-2] by others";

加(假设这些东西在一个更大的 xml 中)

(some xml...)
<Variation id="1">really</Variation>
<Variation id="2">quickly</Variation>
<Variation id="3">strange</Variation>
(some other xml...)
<Variation id="9">definitely</Variation>
(more xml...)

$str = "Hey, I am some text, really a lot of these strange parts will have to definitely go away
and be exchanged quickly by others";

最好的方法是先遍历我的 xml,找出整数有多高,然后再用字符串上的 strpos 进行迭代?

我该如何处理我可能会找到 [var-7] 和 [var-72] 的事实(事先不知道数字的长度)?

这可以用正则表达式来完成吗(假设一旦我有“[var-7]”和“7”作为整数,我仍然需要处理一些东西来知道用什么代替它)?

我希望这个问题很清楚。我的不确定性主要是关于最好的方法,因为我可能能够拼凑出一些东西,但它可能是缓慢而丑陋的。

4

3 回答 3

4

您可以使用preg_replace_callback允许您使用函数作为替换。

$txt = preg_replace_callback('~\[var-(\d+)]~', function ($match) { 
    return $var[$match[1]]; 
}, $txt);

如果要从 XML 文档中提取值,使用 XPath 是一个好方法。例子:

$str = "Hey I am some text,[var-1] a lot of these [var-3] parts will have"
     . " to [var-9] go away and be exchanged [var-2] by others";

$xml = <<<'LOD'
<?xml version="1.0"?>
<Variations>
    <Variation id="1">really</Variation>
    <Variation id="2">quickly</Variation>
    <Variation id="3">strange</Variation>
    <Variation id="9">definitely</Variation>
</Variations>
LOD;

$doc = new DOMDocument();
@$doc->loadXML($xml);
$xpath = new DOMXPath($doc);

$callback = function ($match) use ($xpath) {
    $var_node = $xpath->query("/Variations/Variation[@id='"
                             . $match[1] . "']/text()")->item(0);
    $var_content= $var_node->nodeValue;
    return $var_content;
};

$str = preg_replace_callback('~\[var-(\d+)]~', $callback, $str);
于 2013-07-30T02:04:16.927 回答
2

你最好的选择是使用 preg_replace_callback。在下面的代码中,我直接使用您的数组,但是您说您想从 xml 中读取,因此您从中读取的逻辑将取代简单的数组访问。如果索引与 xml 中的任何内容都不对应,您可能还需要考虑要做什么。在下面的示例中,我假设您根本不想替换它,但这取决于您。

$str = "Hey I am some text,[var-1] a lot of these [var-3] parts will have to [var-9] go away and be exchanged [var-2] by others";


$var[1] = "really";
$var[2] = "quickly";
$var[3] = "strange";
$var[9] = "definitely";

$done = preg_replace_callback('/(?P<original>\[var-(?P<index>\d+)\])/', function($match) use($var) {
    return isset($var[$match['index']]) ? $var[$match['index']] : $match['original'];
}, $str);

echo $done;
于 2013-07-30T02:15:19.023 回答
0

如果您想避免使用 preg_replace_callback 您可以执行以下操作:

while(preg_match('/\[var-(\d+)\]/', $str, $m)){
  $str = preg_replace('/\[var-' . $m[1] . '\]/', $var[$m[1]], $str);
}
于 2013-07-30T05:33:34.817 回答