Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP预匹配所有搜索和替换_Php_Regex_Search_Replace_Preg Match - Fatal编程技术网

PHP预匹配所有搜索和替换

PHP预匹配所有搜索和替换,php,regex,search,replace,preg-match,Php,Regex,Search,Replace,Preg Match,我已经尝试了大约一百万个不同的正则表达式,但我就是无法理解这一个(无可否认,很多正则表达式我都不懂) 在我的文本中,我有如下变量: {{$one}} {{$three.four.five}} {{$six.seven}} $trans = array('{{$testa.testb.testc}}' => 1, '{{$testc.testa}}' => 2, '{{$testf}}' => 3); 我有一个包含所有替换项的数组(“一”的索引是“一”等),但可能缺少一些 如

我已经尝试了大约一百万个不同的正则表达式,但我就是无法理解这一个(无可否认,很多正则表达式我都不懂)

在我的文本中,我有如下变量:

{{$one}}
{{$three.four.five}}
{{$six.seven}}
$trans = array('{{$testa.testb.testc}}' => 1, '{{$testc.testa}}' => 2, '{{$testf}}' => 3);
我有一个包含所有替换项的数组(“一”的索引是“一”等),但可能缺少一些

如果数组存在,我想从数组中替换,如果不存在,则保留文本

我可以使用什么正则表达式来预匹配下面代码段中$text中的所有变量,在适当的情况下从$replace替换并回显到浏览器

<?php
    $replaces = array('testa.testb.testc' => '1', 'testc.testa' => '2', 'testf' => '3');
    $text = '{{$testa.testb.testc}}<br>{{$testc.testa}}<br>{{$testf}}<br>{{$aaaaa}}<br>';

    preg_match_all('/\{\{\$(\w+)\}\}/e', $text, $matches);

    foreach($matches as $match)
    {
        $key = str_replace('{{$', '', $match);
        $key = str_replace('}}', '', $key);

        if(isset($replaces[$key]))
            $text = str_replace($match, $replaces[$key], $text);
    }

    // I want to end up echo'ing:
    //   1<br>2<br>3<br>{{$aaaaa}}<br>

    echo $text;
?>
就像在片段中一样,这是我得到的最接近的

它还必须与变量名中的DO一起工作


提前感谢所有的帮助

这是一个非常好的使用案例,但首先让我们润色一下您的正则表达式:

  • 去掉
    e
    修饰符,它已弃用,您不需要它,因为我们将使用
    preg\u replace\u callback()

  • 我们不需要逃避
    {{}
    在这种情况下,PCRE足够聪明,可以告诉我们它们不是作为量词的

    /{{\$(\w+)}}/
    
  • 由于您的输入中有点,我们需要更改
    \w
    ,否则它将永远不匹配
    [^}]
    是完美的,因为它意味着匹配除
    }

    /{{\$([^}]+)}}/
    
  • 我倾向于使用不同的分隔符,这不是必需的:

    #{{\$([^}]+)}}#
    
  • 让我们开始认真的工作吧,这将是非常有帮助的:

    $replaces = array('testa.testb.testc' => '1', 'testc.testa' => '2', 'testf' => '3');
    $text = '{{$testa.testb.testc}}<br>{{$testc.testa}}<br>{{$testf}}<br>{{$aaaaa}}<br>';
    
    $output = preg_replace_callback('#{{\$([^}]+)}}#', function($m) use ($replaces){
        if(isset($replaces[$m[1]])){ // If it exists in our array
            return $replaces[$m[1]]; // Then replace it from our array
        }else{
            return $m[0]; // Otherwise return the whole match (basically we won't change it)
        }
    }, $text);
    
    echo $output;
    
    $replaces=array('testa.testb.testc'=>1','testc.testa'=>2','testf'=>3');
    $text='{{$testa.testb.testc}}
    {{$testc.testa}}
    {{$testf}}
    {{$aaaaa}
    '; $output=preg_replace_回调('{{\$([^}]+}}}}}}}}',函数($m)use($replaces){ if(isset($replaces[$m[1]]){//如果它存在于数组中 返回$replaces[$m[1]];//然后从数组中替换它 }否则{ return$m[0];//否则返回整个匹配项(基本上我们不会更改它) } }美元文本); echo$输出;

    您只是使用了
    $matches
    而不是
    $matches[0]
    ,这就是您发布的代码不起作用的原因

    而且您的正则表达式不会用
    \w
    计算
    ,所以让我们试试
    [\w.]+

    (我使用了直接包含我们需要的密钥的
    $matches[1]
    ,这样我们就不需要再使用str\u replace两次)


    您不需要使用正则表达式,因为您只处理固定字符串:

    $replaces = array('testa.testb.testc' => 1, 'testc.testa' => 2, 'testf' => 3);
    $keys = array_map(function ($item) {
        return '{{$' . $item . '}}'; }, array_keys($replaces));
    $trans = array_combine($keys, $replaces);
    
    $result = strtr($text, $trans);
    
    请注意,如果您这样编写替换数组,则不需要
    array\u map

    {{$one}}
    {{$three.four.five}}
    {{$six.seven}}
    
    $trans = array('{{$testa.testb.testc}}' => 1, '{{$testc.testa}}' => 2, '{{$testf}}' => 3);
    
    您还可以使用具有自动分隔符的

    使用:

    $output=pattern(“{{\$([^}]+)}”)
    ->替换({{$testa.testb.testc}}
    {{$testc.testa}}
    {{$testf}}
    {{$aaaaaa}
    }) ->全部() ->由() ->第(1)组 ->地图存在者([ 'testa.testb.testc'=>'1', 'testc.testa'=>'2', 'testf'=>'3' ]); }); echo$输出;

    这段代码与@HamZa answer完全相同,但是使用:)

    您是否查看了
    $matches
    中的内容?如果你看一下我添加到你的问题中的链接,你会注意到你的
    循环
    没有像你想象的那样工作。您也不允许在捕获中使用
    。让你一路走到那里;我对正则表达式也不是很在行,所以将
    \w+
    结合起来,允许它捕获一个或多个(而不是三个),我不完全确定该怎么做。刚刚看到HamZa的回答,我让我的一个,因为我发现它不那么复杂:)很好的方法+1,我冒昧地去掉了
    e
    修饰符,去掉了圆点。基本上,在字符类中不需要转义点
    ,它将失去正则表达式的含义。所以
    [。]
    只会匹配一个点。啊,非常感谢,我对逃跑或不逃跑等感到迷茫^^你的回答让我想起了这一点。基本上是+1simplicity@HamZa:谢谢!太神了自上而下的详细解释。谢谢。@HamZa idk我是如何回到这里并注意到您甚至可以这样做的:
    返回isset($replacements[$m[1]])$替换[$m[1]]:$m[0]啊哈:P@Bobot你把我带回来了。事实上,这也是可能的!
    
    $replaces = array('testa.testb.testc' => 1, 'testc.testa' => 2, 'testf' => 3);
    $keys = array_map(function ($item) {
        return '{{$' . $item . '}}'; }, array_keys($replaces));
    $trans = array_combine($keys, $replaces);
    
    $result = strtr($text, $trans);
    
    $trans = array('{{$testa.testb.testc}}' => 1, '{{$testc.testa}}' => 2, '{{$testf}}' => 3);
    
    $output = pattern('{{\$([^}]+)}}')
        ->replace('{{$testa.testb.testc}}<br>{{$testc.testa}}<br>{{$testf}}<br>{{$aaaaa}}<br>')
        ->all()
        ->by()
        ->group(1)
        ->mapIfExists([
           'testa.testb.testc' => '1', 
           'testc.testa' => '2',
           'testf' => '3'
        ]);
    });
    
    echo $output;