用于替换字符的递归PHP函数

用于替换字符的递归PHP函数,php,string,function,recursion,replace,Php,String,Function,Recursion,Replace,我正在尝试开发一个递归函数,可以用来剥离多个值的字符串实例 这就是我到目前为止所做的: $words = 'one__two_"__three'; $words = stripall(array('__', '"'), '_', $words); echo $words; function stripall($values, $replace, $string) { foreach ($values as $value) {

我正在尝试开发一个递归函数,可以用来剥离多个值的字符串实例

这就是我到目前为止所做的:

$words = 'one__two_"__three';

$words = stripall(array('__', '"'), '_', $words);

echo $words;

function stripall($values, $replace, $string) {
            
    foreach ($values as $value) {
        
        if (strpos($string, $value)) {
            
            $string = str_replace($value, $replace, $string);
            
            stripall($values, $replace, $string);
        }
    }
    
    return $string;
}
在这里,$words字符串将从两个下划线(_u)或引号(“)的所有实例中删除。或者至少在理论上

目标返回值为:

one_two_three

然而,我得到的是“一、二、三”

我对您的预期输出有点困惑:

one_two_three
假设您的字符串:

$words = 'one__two_"__three';
你的规则是:

这里是$words字符串 除去所有两个实例 下划线(\)或引号(“”)

我们会像这样剥去绳子:

$words = 'one[__]two_["][__]three';
因此,您的预期输出应该是:

onetwo_three
通过使用以下数组形式:

我得到的正是这个输出:

$ php test.php
onetwo_three

这个功能完全没有必要
str_replace
已经做了同样的事情。

你想试试我的吗

//Example:
/*
    $data = strReplaceArrayRecursive(
        array('{name}'=>'Peter','{profileImg}'=>'./PRF-AAD036-51dc30ddc4.jpg'),
        array(
            'title'=>'My name is {name}',
            'post'=>array(
                'author' => '{name}',
                'image' => '{profileImg}',
                'content' => 'My post.'
            )
        )
    );
    print_r($data);
//Expect:
Array
(
    [title] => My name is Peter
    [post] => Array
        (
            [author] => Peter
            [image] => ./PRF-AAD036-51dc30ddc4.jpg
            [content] => My post.
        )

)
*/
function strReplaceArrayRecursive($replacement=array(),$strArray=false,$isReplaceKey=false){
    if (!is_array($strArray)) {
        return str_replace(array_keys($replacement), array_values($replacement), $strArray);
    }
    else {
        $newArr = array();
        foreach ($strArray as $key=>$value) {
            $replacedKey = $key;
            if ($isReplaceKey) {
                $replacedKey = str_replace(array_keys($replacement), array_values($replacement), $key);
            }
            $newArr[$replacedKey] = strReplaceArrayRecursive($replacement, $value, $isReplaceKey);
        }
        return $newArr;
    }
}

将IF改为While和first remove,然后检查

我不认为有人能说服我使用循环或非正则方法来处理这个问题。如果有人不使用正则表达式,我会认为他们根本不理解在不同字符序列上执行替换的能力和效用

该模式仅扫描输入字符串并替换一个或多个下划线和/或双引号的所有序列

这种技术唯一不必要的副作用(但不会对结果产生负面影响)是,它将不必要地用一个下划线替换一个下划线。理想情况下,模式不应设计为进行不必要的匹配/替换,但在这种情况下,它不需要对字符串进行第二次扫描清除任何新生成的连续下划线

这只需一个函数调用就可以完美地整理文本——这正是正则表达式存在的原因

代码:()

输出:

array (
  0 => 'one_two_three',
  1 => 'one_two_three',
  2 => 'one_two_three',
  3 => 'one_two_three',
)

可能他想用
”替换所有的
?是的,Jaitsu明白了。我正试图用单数替换所有的双下划线。我可能有一个带有多个下划线的字符串,我希望所有连续的都替换为一个。而onteria,如果我运行你所做的,我会得到“一、二、三”(注意三重下划线)False。如果这样运行,我仍然会得到三重下划线的“一、二、三”结果。您可以使用preg\u replace\u回调而不是str\u replace。没有有效的理由为此任务使用
preg\u replace\u回调()
。因为有一个
后跟一个
过滤后变成
\uu
,然后有一个
\u
变成
\u
,结果是一个
\u
——只需将函数中的
条带($values,$replace,$string)
添加到:
返回条带($values,$replace,$string)如果“瘦”的意思是“瘦”的解决方案,如果瘦的意思是“瘦”,就像一个拐杖。FWW你的表达式数组可以简化成一个表达式,它不取决于应用时的顺序:<代码> PrggRead('/[vi] +/','',$string)< /Cord> >我称之为“瘦”。“因为它的执行是直接的。我同意你的模式建议,很明显我考虑过了,所以我会更新我的答案。干杯@Tha幸运的是,我的攻击者已经离开了我的答案,现在正在对我的问题执行一个非常谨慎/可控的每日DV——我没有太多问题要攻击:).所以检测所谓的。我很好奇你对preg*
的理解,因为它们的使用绝不是直接的。有一个完整的语法、词法分析器、解析器和求值器来支持正则表达式操作。从初学者的角度来看,正则表达式“引擎”是一顶神奇的帽子,里面的字符串看起来很有趣,答案神秘地弹出。除非你对语法和特征有很深的了解,否则很难调试。我很喜欢正则表达式,所以我不认为它是魔法。我认为在这种情况下是非常合适的。如果你不认为一个单独的预通话是直接的,那么我担心你会反对regex。根据我的经验,连续投票的检测非常差,当它检测到时,它只会将分数返回给违规者,然后他们会学习调整攻击速度,以便脚本不会检测到它。在这种情况下,影响不仅仅是我帖子上的DV,还有其他帖子上的UV(我不会赞同)——所有这些都是为了让研究人员远离我的建议。
while(strpos(…)
可以评估为
while(0)
,这将退出循环,而且不应该。系统明确表示使用
==false
$words = 'one__two_"__three';
$words = stripall(array('"','__'), '_', $words);
echo $words;
function stripall($values, $replace, $string) {
    foreach ($values as $value) {
        while (strpos($string, $value)) {
            $string = str_replace($value, $replace, $string);
            stripall($values, $replace, $string);
        }
    }
    return $string;
}
$strings = [
    'one"two_"_"_three',
    'one__two_"__three',
    'one__two_"__""____"three',
    'one__two___"""""""______three',
];

var_export(
    preg_replace('~["_]+~', '_', $strings)
);
array (
  0 => 'one_two_three',
  1 => 'one_two_three',
  2 => 'one_two_three',
  3 => 'one_two_three',
)