PhP函数将括号中的单词替换为字符,并将其值存储在数组中


PhP Function to replace words in brackets with a character and store their values in array

我正在寻找一个函数,用于用特定字符替换括号中的一些单词,并将值存储在数组中。我正在寻找这样的东西:

example 1: test(word1,word2)-->test(_,_) -->array[word1,word2]
example 2: test(word1(word11),word2,word3(word33(word333,word3333)))-->test(_,_,_) -->array[word1(word11),word2,word3(word33(word333,word3333))]

我认为您必须逐个字母地遍历字符串。你把每个字母钉在一个缓冲区里。然后你会记录在第一个括号之后你看到了多少个左括号。每次遇到逗号时,都会将字符串的前一部分保存到集合数组中,除非至少遇到一个左括号。在这种情况下,你加上逗号。每次遇到左括号时,递增括号计数器,每次遇到右括号时,递减括号计数器。当括号计数器get回到零(或者在本例中为1)时,您将返回到逗号行为的"保存上一个字符串"。

哦,在执行此操作的同时,当保存上一个字符串时,还会向返回值/output/post-replaced字符串发出一个"_",还会发出逗号等。

至少这是算法的描述,如果你能遵循它,它应该相当简单。

您可以使用以下模式使用preg_match_all解决问题:regex101

$pattern = <<<'EOD'
~
(?:
    'G(?!'A)                  # contiguous to a previous match
    (?: ,| ') 'z (*ACCEPT) )  # a comma or a closing bracket at the string end
  |                           # OR
    'A (?<func> 'w+ ) '(      # the function name at the start of the string
)
(?:
    (?<param>                 # named capture "param"
        (?:
            'w+               # param element
            (?:               # optional part between parenthesis
                '(
                'g<param>     # recursive call to the param subpattern
                (?:, 'g<param> )* # optional elements separated by commas 
                ')
            )?
        )
    )
)? # makes the params optional (remove it if you don't want to allow this case)
~x
EOD;

这种模式有两个特点:

  • 标记先前匹配结果的结束并且对于获得连续结果是有用的CCD_ 2锚。(连续结果的优点是提取您想要的信息(作为经典模式),同时检查字符串格式)。

  • 递归。命名的子模式"param"调用自身来处理嵌套的括号。

(*ACCEPT)是一个回溯控制动词,当它到达时,模式立即成功。

如果字符串格式正确,则会获得不存在捕获"param"的最后一个匹配结果。这是一种方便的方法,可以测试字符串格式从字符串开始到结束是否正确。

让我们看看它在这个示例代码中的作用:ideone

class StrFunc {
    private $raw;
    private $isBuild = false;
    private $funcName;
    private $func;
    private $params;
    private $nbParams;
    const PATTERN = '~(?:'G(?!'A)(?:,|')'z(*ACCEPT))|'A(?<func>'w+)'()(?:(?<param>(?:'w+(?:'('g<param>(?:,'g<param>)*'))?)))?~';
    public function __construct($raw = null) {
        $this->raw = $raw;  
        if ($raw) $this->createFromRaw();
    }
    public function createFromRaw() {
        if ( !$this->isBuild &&
             preg_match_all(self::PATTERN, $this->raw, $m, PREG_SET_ORDER) &&
             !isset(end($m)['param']) ) {
            $this->params = array_column($m, 'param');
            $this->funcName = $m[0]['func'];
            $this->nbParams = count($this->params);
            $this->func = $this->funcName . '(' 
                        . ( ($this->nbParams)
                          ? implode(',', array_fill(1, $this->nbParams, '_'))
                          : '' )
                        . ')';
            $this->isBuild = true;
        }
    }
    public function setRaw($raw) {
        $this->isBuild = false;
        $this->raw = $raw;
    }
    public function getFuncName() {
        return ($this->isBuild) ? $this->funcName : $this->isBuild; 
    }
    public function getFunc() {
        return ($this->isBuild) ? $this->func : $this->isBuild;
    }
    public function getParams() {
        return ($this->isBuild) ? $this->params : $this->isBuild;
    }
};
$tests = array('test(word1,word2)',
               'huitre(word1(word11),word2,word3(word33(word333,word3333)))',
               'splitz()');
foreach ($tests as $k=>$test) {
    $strFunc[$k] = new StrFunc($test);
    echo $strFunc[$k]->getFuncName() . "'n"
       . $strFunc[$k]->getFunc() . "'n"
       . print_r($strFunc[$k]->getParams(), true) . "'n";
}

此示例代码是为PHP 5.5编写的。要使其适应以前的PHP版本,您需要将$this->params = array_column($m, 'param');替换为:

foreach($m as $match) {
    if (isset($match['param']))
        $this->params[] = $match['param'];
}

如果您遇到!isset(end($m)['param'])的问题,您可以将其替换为:

!isset($m[count($m)-1]['param'])