PHP字符串交叉,贪婪地从左从右剥离
我希望从另一个字符串 $right
的左侧剥离一个字符串 $left
。给定:
$left = 'alpha beta gamma';
$right = 'beta gamma delta';
期望的输出是:
string(6) " delta"
现在,我已经完成了这一点。我写了一个函数,来准确地实现这一点:
function strip_left_from_right($left, $right){
for($i = 0, $m = strlen($left); $i <= $m; $i++){
$needle = substr($left, -$i);
if(substr($right, 0, strlen($needle)) == $needle){
return substr($right, strlen($needle));
}
}
}
并且它工作得很好。不过,我希望它是“贪婪的”,尽可能多地使用 $left
字符串。例如:
$left = "foofoofoofoo";
$right = "foofoofoobar";
// desired output
string(3) "bar"
// actual output
string(9) "foofoobar"
本质上我的问题有两个方面:
1.执行“贪婪”匹配的最佳方式是什么? (假设我继续使用此代码)
并且可能更重要;
2.有没有更好的(非迭代,串联使用的一组核心函数)方法来完成此任务?
我采用的解决方案,感谢@Yoshi 让我的大脑朝着这个方向发展:
function intersect_split($left, $right, $greedy = true){
for($i = 0, $m = strlen($left); $i <= $m; $i++){
$chunk = substr($left, $i * (int) ($greedy ?: -1));
if(substr($right, 0, strlen($chunk)) == $chunk){
return array(
(string) substr($left, 0, $m - strlen($chunk)),
(string) substr($right, strlen($chunk)),
);
}
}
return array($left, $right);
}
$left = 'foo bar bar bar bar';
$right = 'bar bar bar bar baz';
var_dump( intersect_split($left, $right, true) );
var_dump( intersect_split($left, $right, false) );
产生:
array(2) {
[0]=>
string(4) "foo "
[1]=>
string(4) " baz"
}
array(2) {
[0]=>
string(16) "foo bar bar bar "
[1]=>
string(16) " bar bar bar baz"
}
所以现在我基本上在 $left
参数右侧和 $right
参数左侧的相交匹配处分割字符串,生成前导和尾随字符串在一个数组中。 $greedy
产生明显的结果差异。
I'm looking to strip a string, $left
from the left of another string, $right
. Given:
$left = 'alpha beta gamma';
$right = 'beta gamma delta';
The desired output would be:
string(6) " delta"
Now, I've sort of accomplished this. I've written a function, to achieve this exactly:
function strip_left_from_right($left, $right){
for($i = 0, $m = strlen($left); $i <= $m; $i++){
$needle = substr($left, -$i);
if(substr($right, 0, strlen($needle)) == $needle){
return substr($right, strlen($needle));
}
}
}
And it works fine. However I want it to be be "greedy", using as much of the $left
string as possible. For instance:
$left = "foofoofoofoo";
$right = "foofoofoobar";
// desired output
string(3) "bar"
// actual output
string(9) "foofoobar"
Essentially my question is two-fold;
1. What would be the best way to perform a "greedy" match? (given I continue with this code)
And probably more important;
2. Is there a better (non-iterative, set of core functions used in tandem) way to accomplish this?
The solution I went with, thanks to @Yoshi for getting my brain in that direction:
function intersect_split($left, $right, $greedy = true){
for($i = 0, $m = strlen($left); $i <= $m; $i++){
$chunk = substr($left, $i * (int) ($greedy ?: -1));
if(substr($right, 0, strlen($chunk)) == $chunk){
return array(
(string) substr($left, 0, $m - strlen($chunk)),
(string) substr($right, strlen($chunk)),
);
}
}
return array($left, $right);
}
$left = 'foo bar bar bar bar';
$right = 'bar bar bar bar baz';
var_dump( intersect_split($left, $right, true) );
var_dump( intersect_split($left, $right, false) );
Produces:
array(2) {
[0]=>
string(4) "foo "
[1]=>
string(4) " baz"
}
array(2) {
[0]=>
string(16) "foo bar bar bar "
[1]=>
string(16) " bar bar bar baz"
}
So now I essentially split the string at an intersecting match of the right of the $left
argument and left of the $right
argument, producing the leading and trailing strings in an array. $greedy
produces the obvious difference in results.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不是最佳的,但至少它完成了工作:
Not optimal, but at least it does the job: