PHP:preg_replace(x)出现了吗? [英] PHP: preg_replace (x) occurrence?
问题描述
我最近问了一个类似的问题,但是由于我太具体了而没有得到明确的答案.这是更广泛的.
有人知道如何替换正则表达式模式中的(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屋!