有两个数组:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
第二个数组中的元素数小于或等于第一个数组。
将第一个数组和第二个数组排序,如果第二个数组的元素包含在第一个数组的元素的末尾,则按以下形式对数组进行排序:
Array
(
[0] => w_ord
[1] => tech
[2] => care
[3] => k_ek
[4] => l_ol
[5] => wi_ld
[6] => re_gex
)
重要提示:第二个数组的元素从不重复,并且可以按任何顺序排列。如果在第二个元素中,第一个数组的元素没有结尾,则设置第一个数组的元素的值。
我这样做:
foreach($arr2 as $val) {
$strrepl[$val] = "_".$val;
}
foreach($arr1 as $key => $val) {
$arr3[$key] = str_replace(array_keys($strrepl), $strrepl, $val);
}
print_r($arr3);
但是我不确定这是正确的方法,您有何建议?
答案 0 :(得分:5)
嗯,让我们看看...纯粹是功能性的,因为您知道:D
function ends($str) {
return function($suffix) use($str) {
return mb_strlen($str) >= mb_strlen($suffix)
&& mb_substr($str, mb_strlen($suffix) * -1) === $suffix;
};
}
$result = array_map(function($item) use($arr2) {
$filter = ends($item);
$suffixes = array_filter($arr2, $filter);
if (empty($suffixes)) {
return $item;
}
// This only cares about the very first match, but
// is easily adaptable to handle all of them
$suffix = reset($suffixes);
return mb_substr($item, 0, mb_strlen($suffix) * -1) . "_{$suffix}";
}, $arr1);
答案 1 :(得分:3)
令人惊讶的是,这个程序执行起来很有趣。 由于您在元素的 end 上非常具体,因此我决定为此使用RegEx。
这是我的方法:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
foreach ($arr2 as $find) {
foreach ($arr1 as $key => $element) {
$arr1[$key] = preg_replace('/' . $find . '$/', '_' . $find, $element);
}
}
对于第二个数组的每个元素(由于它们不再重复),我遍历第一个数组的每个元素,并检查是否可以使用{{1在第二个数组的元素末尾找到该值}}来自RegEx的锚点,它迫使它从字符串的末尾看。
通过这种方式,$ arr1可以完全满足您的期望。
[编辑] 遵循@aefxx提出的建议,并改进了变量名。
答案 2 :(得分:2)
您可以在数组上使用正则表达式preg_grep。
此代码还将确保它可以从$ arr1输出多个匹配的单词。
$arr1 = ['word', 'chord', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$keys=[];
foreach($arr2 as $val){
$matches = preg_grep("/.+" . preg_quote($val) . "/", $arr1);
$keys = array_merge($keys, array_keys($matches)); // save keys of matched words
foreach($matches as $key => $m) $new[$val][] = str_replace($val, "_$val", $arr1[$key]);
}
$new['unmatched'] = array_diff_key($arr1, array_flip($keys)); // add unmatched words
var_dump($new);
输出:
array(6) {
["ord"]=>
array(2) {
[0]=>
string(5) "w_ord"
[1]=>
string(6) "ch_ord"
}
["ek"]=>
array(1) {
[0]=>
string(4) "k_ek"
}
["ol"]=>
array(1) {
[0]=>
string(4) "l_ol"
}
["ld"]=>
array(1) {
[0]=>
string(5) "wi_ld"
}
["gex"]=>
array(1) {
[0]=>
string(6) "re_gex"
}
["unmatched"]=>
array(2) {
[2]=>
string(4) "tech"
[3]=>
string(4) "care"
}
}
答案 3 :(得分:1)
您可以尝试一下。我认为这很容易理解:
$arr1=['word','tech','care','kek','lol','wild','regex'];
$arr2=['ord','ek','ol','ld','gex','ss'];
foreach($arr1 as $key=>$fullword){
foreach($arr2 as $substr){
$arr1[$key]=preg_replace('/' . $substr . '$/', '_' . $substr, $fullword,-1,$count);
if($count) break;
}
}
我遍历全字词数组,一旦找到匹配项,我便停止搜索。
答案 4 :(得分:1)
另一种方法可以是预先创建复杂的正则表达式(为安全起见使用implode
和preg_quote
并在array_map
回调中将其替换:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$regex = '/(' . implode('|', array_map('preg_quote', $arr2)) . ')$/';
$result = array_map(function ($word) use ($regex) {
return preg_replace($regex, '_$1', $word);
}, $arr1);
这里是the demo。