2011-03-10 50 views
11

非常簡單;我似乎無法找到有關PHP的支持preg_replace()命名後向引用任何明確的:用preg_replace命名的反向引用

// should match, replace, and output: user/profile/foo 
$string = 'user/foo'; 
echo preg_replace('#^user/(?P<id>[^/]+)$#Di', 'user/profile/(?P=id)', $string); 

這是一個簡單的例子,但我想知道,如果這句法,(?P=name)是根本不支持。語法問題,還是不存在的功能?

回答

10

它們的存在:

http://www.php.net/manual/en/regexp.reference.back-references.php

隨着preg_replace_callback:

function my_replace($matches) { 
    return '/user/profile/' . $matches['id']; 
} 
$newandimproved = preg_replace_callback('#^user/(?P<id>[^/]+)$#Di', 'my_replace', $string); 

甚至更​​快

$newandimproved = preg_replace('#^user/([^/]+)$#Di', '/user/profile/$1', $string); 
+1

**感謝德米特里; **如果答案是*不*支持,那我就簡單地恢復到編號引用。 – Dan 2011-03-10 03:42:25

+1

您可以使用帶有preg_replace_callback的命名匹配。 – Dimitry 2011-03-10 03:51:49

+0

啊,從數組參數...很好知道,但不符合這裏的目的。該死,屁股疼得厲害。 – Dan 2011-03-10 03:53:31

1

preg_replace不支持命名的子模式呢。

4

preg_replace不支持命名的反向引用。

preg_replace_callback支持命名反向引用,但是在PHP 5.3之後,所以期望它在PHP 5.2及更低版本上失敗。

+1

「對命名子模式的反向引用可以通過(?P = name)來實現,或者從PHP 5.2.2開始,也可以通過\ k 或\ k'name'來實現。此外,PHP 5.2.4增加了對\ k {name }和\ g {name}。「這個引用(來自Dimitry提供的鏈接)僅適用於'preg_match()'和'preg_match_all()',是否正確? – Dan 2011-03-10 03:50:42

+0

是的,它只適用於模式。 – Thai 2011-03-10 04:49:37

0

您可以使用此:

class oreg_replace_helper { 
    const REGEXP = '~ 
(?<!\x5C)(\x5C\x5C)*+ 
(?: 
    (?: 
     \x5C(?P<num>\d++) 
    ) 
    | 
    (?: 
     \$\+?{(?P<name1>\w++)} 
    ) 
    | 
    (?: 
     \x5Cg\<(?P<name2>\w++)\> 
    ) 
)? 
~xs'; 

    protected $replace; 
    protected $matches; 

    public function __construct($replace) { 
     $this->replace = $replace; 
    } 

    public function replace($matches) { 
     var_dump($matches); 
     $this->matches = $matches; 
     return preg_replace_callback(self::REGEXP, array($this, 'map'), $this->replace); 
    } 

    public function map($matches) { 
     foreach (array('num', 'name1', 'name2') as $name) { 
      if (isset($this->matches[$matches[$name]])) { 
       return stripslashes($matches[1]) . $this->matches[$matches[$name]]; 
      } 
     } 
     return stripslashes($matches[1]); 
    } 
} 

function oreg_replace($pattern, $replace, $subject) { 
    return preg_replace_callback($pattern, array(new oreg_replace_helper($replace), 'replace'), $subject); 
} 

,那麼你可以使用\g<name> ${name} or $+{name}在你的REPLACE語句引用。

CF(http://www.rexegg.com/regex-disambiguation.html#namedcapture