一般的な検索文字列と PCRE のバージョンに応じて、 または のいずれpreg_replace
かstrrpos
がおそらく最適です。
機能
function usingExplode($string, $replacement) {
$pieces = explode('_', $string);
array_pop($pieces);
return implode('_', array_merge($pieces, array($replacement)));
}
function usingStrrpos($string, $replacement) {
return substr($string, 0, strrpos($string, '_') + 1) . $replacement;
}
function usingPreg($string, $replacement) {
return preg_replace('/_[^_]*$/', '_' . $replacement, $string);
}
テストハーネス
function speedTest($function, $string, $count = 100000) {
$start = microtime(true);
for ($i = 0; $i < $count; $i++) {
$function($string, 'replacement');
}
$end = microtime(true);
printf('%-12s: %01.2fs%s', $function, $end - $start, PHP_EOL);
}
$tests = array('a_b_c', 'abcdefghijklmnopqrstuvwxy_z', 'a_bcdefghijklmnopqrstuvwxyz', 'a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z');
foreach ($tests as $test) {
echo $test . ':' . PHP_EOL;
speedTest('usingExplode', $test);
speedTest('usingStrrpos', $test);
speedTest('usingPreg', $test);
echo PHP_EOL;
}
結果
a_b_c:
usingExplode: 0.64s
usingStrrpos: 0.34s
usingPreg : 0.33s
abcdefghijklmnopqrstuvwxy_z:
usingExplode: 0.61s
usingStrrpos: 0.32s
usingPreg : 0.32s
a_bcdefghijklmnopqrstuvwxyz:
usingExplode: 0.60s
usingStrrpos: 0.32s
usingPreg : 0.32s
a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z:
usingExplode: 1.39s
usingStrrpos: 0.32s
usingPreg : 0.71s
(少なくとも PHP 5.4.0 を使用した私のセットアップでpreg_replace
は)、strrpos
最後のアンダースコアの前に多数のアンダースコアが表示されるまで、そのお金のために実行されることに注意してください。
編集: bfrohs の正規表現をスイートにプラグインしましたが、置換するアンダースコアが文字列の先頭近くにない限り、うまく機能しません:
a_b_c:
usingPreg2: 0.40s
abcdefghijklmnopqrstuvwxy_z:
usingPreg2: 1.91s
a_bcdefghijklmnopqrstuvwxyz:
usingPreg2: 0.38s
a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z:
usingPreg2: 1.04s