PHP:preg_replace(x)出现了吗? [英] PHP: preg_replace (x) occurrence?

查看:83
本文介绍了PHP:preg_replace(x)出现了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近问了一个类似的问题,但是由于我太具体了而没有得到明确的答案.这是更广泛的.

有人知道如何替换正则表达式模式中的(x)项吗?

示例:假设我要替换字符串中第5次出现的正则表达式模式.我该怎么办?

以下是模式: preg_replace('/{(.*?)\|\:(.*?)}/', 'replacement', $this->source);

@anubhava要求的示例代码(最后一个功能不起作用):


$sample = 'blah asada asdas  {load|:title} steve jobs {load|:css} windows apple ';


$syntax = new syntax();
$syntax->parse($sample);


class syntax {

    protected $source;
    protected $i;
    protected $r;

        // parse source
    public function parse($source) {
                // set source to protected class var
        $this->source = $source;

        // match all occurrences for regex and run loop
        $output = array();
        preg_match_all('/\{(.*?)\|\:(.*?)\}/', $this->source, $output);

                // run loop
        $i = 0;
        foreach($output[0] as $key):
            // perform run function for each occurrence, send first match before |: and second match after |:
            $this->run($output[1][$i], $output[2][$i], $i);

            $i++;
        endforeach;

        echo $this->source;

    }

        // run function
    public function run($m, $p, $i) {
                // if method is load perform actions and run inject
        switch($m):

            case 'load':
                $this->inject($i, 'content');
            break;

        endswitch;

    }

        // this function should inject the modified data, but I'm still working on this.
    private function inject($i, $r) {

          $output = preg_replace('/\{(.*?)\|\:(.*?)\}/', $r, $this->source);

    }


}


解决方案

您误解了正则表达式:它们是无状态的,没有内存,也没有计数能力,什么也没有,所以您不知道匹配是字符串中的第x个匹配项-正则表达式引擎没有任何提示.出于相同的原因,您无法使用正则表达式执行此类操作,原因是无法编写正则表达式来查看字符串是否具有平衡的括号:问题需要一个内存,根据定义,正则表达式没有该内存./p>

但是,正则表达式引擎可以告诉您所有匹配项,因此最好使用preg_match()获取匹配项列表,然后自己使用该信息来修改字符串.

更新:这更接近您的想法了吗?

<?php
class Parser {

    private $i;

    public function parse($source) {
        $this->i = 0;
        return preg_replace_callback('/\{(.*?)\|\:(.*?)\}/', array($this, 'on_match'), $source);
    }

    private function on_match($m) {
        $this->i++;

        // Do what you processing you need on the match.
        print_r(array('m' => $m, 'i' => $this->i));

        // Return what you want the replacement to be.
        return $m[0] . '=>' . $this->i;
    }
}

$sample = 'blah asada asdas  {load|:title} steve jobs {load|:css} windows apple ';
$parse = new Parser();
$result = $parse->parse($sample);
echo "Result is: [$result]\n";

哪个给...

Array
(
    [m] => Array
        (
            [0] => {load|:title}
            [1] => load
            [2] => title
        )

    [i] => 1
)
Array
(
    [m] => Array
        (
            [0] => {load|:css}
            [1] => load
            [2] => css
        )

    [i] => 2
)
Result is: [blah asada asdas  {load|:title}=>1 steve jobs {load|:css}=>2 windows apple ]

I asked a similar question recently, but didn't get a clear answer because I was too specific. This one is more broad.

Does anyone know how to replace an (x) occurrence in a regex pattern?

Example: Lets say I wanted to replace the 5th occurrence of the regex pattern in a string. How would I do that?

Here is the pattern: preg_replace('/{(.*?)\|\:(.*?)}/', 'replacement', $this->source);

@anubhava REQUESTED SAMPLE CODE (last function doesn't work):


$sample = 'blah asada asdas  {load|:title} steve jobs {load|:css} windows apple ';


$syntax = new syntax();
$syntax->parse($sample);


class syntax {

    protected $source;
    protected $i;
    protected $r;

        // parse source
    public function parse($source) {
                // set source to protected class var
        $this->source = $source;

        // match all occurrences for regex and run loop
        $output = array();
        preg_match_all('/\{(.*?)\|\:(.*?)\}/', $this->source, $output);

                // run loop
        $i = 0;
        foreach($output[0] as $key):
            // perform run function for each occurrence, send first match before |: and second match after |:
            $this->run($output[1][$i], $output[2][$i], $i);

            $i++;
        endforeach;

        echo $this->source;

    }

        // run function
    public function run($m, $p, $i) {
                // if method is load perform actions and run inject
        switch($m):

            case 'load':
                $this->inject($i, 'content');
            break;

        endswitch;

    }

        // this function should inject the modified data, but I'm still working on this.
    private function inject($i, $r) {

          $output = preg_replace('/\{(.*?)\|\:(.*?)\}/', $r, $this->source);

    }


}


解决方案

You're misunderstanding regular expressions: they're stateless, have no memory, and no ability to count, nothing, so you can't know that a match is the x'th match in a string - the regex engine doesn't have a clue. You can't do this kind of thing with a regex for the same reason as it's not possible to write a regex to see if a string has balanced brackets: the problem requires a memory, which, by definition, regexes do not have.

However, a regex engine can tell you all the matches, so you're better off using preg_match() to get a list of matches, and then modify the string using that information yourself.

Update: is this closer to what you're thinking of?

<?php
class Parser {

    private $i;

    public function parse($source) {
        $this->i = 0;
        return preg_replace_callback('/\{(.*?)\|\:(.*?)\}/', array($this, 'on_match'), $source);
    }

    private function on_match($m) {
        $this->i++;

        // Do what you processing you need on the match.
        print_r(array('m' => $m, 'i' => $this->i));

        // Return what you want the replacement to be.
        return $m[0] . '=>' . $this->i;
    }
}

$sample = 'blah asada asdas  {load|:title} steve jobs {load|:css} windows apple ';
$parse = new Parser();
$result = $parse->parse($sample);
echo "Result is: [$result]\n";

Which gives...

Array
(
    [m] => Array
        (
            [0] => {load|:title}
            [1] => load
            [2] => title
        )

    [i] => 1
)
Array
(
    [m] => Array
        (
            [0] => {load|:css}
            [1] => load
            [2] => css
        )

    [i] => 2
)
Result is: [blah asada asdas  {load|:title}=>1 steve jobs {load|:css}=>2 windows apple ]

这篇关于PHP:preg_replace(x)出现了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆