Я никогда не видел, чтобы тернарный оператор злоупотребляли так сильно, простой if(condition) { statement }был бы намного понятнее.
Тату Улманен
4
@salathe: Я принимаю критику. Было личным любопытством увидеть, что будет быстрее всего.
Фабио Мора
51
@salathe, я не понимаю. Были предложены как идиоматические решения, так и решения на основе регулярных выражений: сравнение этих двух с точки зрения эффективности помогает найти лучший (опять же с точки зрения эффективности) ответ. Почему это зло?
cbrandolino
5
@cbrandolino, никто не сказал, что это зло . Я просто подумал, что это совершенно не имеет отношения к вопросу; во многом как «вот два решения, а вот изображение котят, получивших больше голосов».
Салате
5
if (substr($str, 0, strlen($prefix)) == $prefix) может быть изменен, if (0 === strpos($str, $prefix))чтобы избежать ненужного выделения памяти при сохранении той же читабельности :)
xDaizu 01
63
Вы можете использовать регулярные выражения с символом вставки ( ^), который привязывает совпадение к началу строки:
Интересно, работает ли он быстрее, чем substr()версия ... Я думаю, что да, и должен быть отмечен как правильный ответ.
Flash Thunder
за исключением того, что это должно быть preg_quote'd
vp_arth
Я думаю, что это гораздо менее болезненно для глаз программиста и более интуитивно понятно. Даже если он проигрывает другому предлагаемому решению (в чем я действительно сомневаюсь), я все равно предпочел бы это.
Fr0zenFyr
multibyteкошмар - еще одна проблема с другими решениями, хотя это хорошо работает, если кодировка файла правильная. В любом случае, это не должно входить в рамки этого вопроса, поэтому мне было бы все равно.
Fr0zenFyr
Вернулся, чтобы упомянуть, что это дает дополнительное преимущество работы с массивом строк темы. substrи strposне может принять массив. Вот и все, определенное увеличение производительности, если вы имеете дело с массивом. Ура!
Что бы это ни стоило, поскольку здесь все, кажется, микрооптимизируются, этот, по моим подсчетам, неизменно самый быстрый. 1 миллион итераций произошел за 0,17 секунды, тогда как (substr($str, 0, strlen($prefix)) == $prefix)из принятого ответа было больше похоже на
Вы можете использовать параметр count str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ), это позволит вам ограничить количество замен, начиная слева, но это не будет заставлять это быть в начале.
substr_replaceзаменит символы в заданном диапазоне независимо от того, хотите ли вы удалить префикс или что-то еще. OP хочет удалить, bla_«только если он находится в начале строки».
Оливье «Олбаум» Шерлер,
0
Хорошая скорость, но она жестко запрограммирована в зависимости от стрелки, оканчивающейся на _. Есть общая версия? - toddmo 29 июня в 23:26
Ожидается, str_replace()что $countпараметром функции будет переменная, переданная по ссылке и содержащая количество найденных замен, а не ограничение количества замен.
AL the X
-6
Удалите www. от начала строки, это самый простой способ (ltrim)
Второй параметр - это карта символов, которые нужно удалить с левой стороны строки ( php.net/manual/function.ltrim.php ). Следовательно: ltrim($a, "w.");будет выполнять работу только в том случае, если домен не начинается с буквы «w». ltrim ('m.google.com', ".omg")приводит к le.com.
fragmentedreality
но он решает конкретную проблему вопроса, +1
chulian 05
1
это действительно решает конкретную проблему, которую он поставил для своего ответа, а не проблему вопроса. даже если бы вы пошли ltrim, он используется неправильно. второй параметр - это список символов, которые следует обрезать; поэтому одного "w."будет достаточно.
fragmentedreality
Я думаю, ИМХО, это правильно для вопроса и для проблемы.
abkrim
2
После теста с несколькими тестами мое мнение изменилось .... не
s($str)->replacePrefix('_bla')
полезные сведения, найденные в этой автономной библиотеке .Ответы:
Простая форма без регулярного выражения:
$prefix = 'bla_'; $str = 'bla_string_bla_bla_bla'; if (substr($str, 0, strlen($prefix)) == $prefix) { $str = substr($str, strlen($prefix)); }
Требуется : 0,0369 мс (0,000 036,954 секунды)
И с:
$prefix = 'bla_'; $str = 'bla_string_bla_bla_bla'; $str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);
Требуется : 0,1749 мс (0,000 174 999 секунд) при первом запуске (компиляция) и 0,0510 мс (0,000 051 021 секунда) после.
Очевидно, профилированы на моем сервере.
источник
if(condition) { statement }
был бы намного понятнее.if (substr($str, 0, strlen($prefix)) == $prefix)
может быть изменен,if (0 === strpos($str, $prefix))
чтобы избежать ненужного выделения памяти при сохранении той же читабельности :)Вы можете использовать регулярные выражения с символом вставки (
^
), который привязывает совпадение к началу строки:$str = preg_replace('/^bla_/', '', $str);
источник
substr()
версия ... Я думаю, что да, и должен быть отмечен как правильный ответ.preg_quote
'dmultibyte
кошмар - еще одна проблема с другими решениями, хотя это хорошо работает, если кодировка файла правильная. В любом случае, это не должно входить в рамки этого вопроса, поэтому мне было бы все равно.substr
иstrpos
не может принять массив. Вот и все, определенное увеличение производительности, если вы имеете дело с массивом. Ура!function remove_prefix($text, $prefix) { if(0 === strpos($text, $prefix)) $text = substr($text, strlen($prefix)).''; return $text; }
источник
.''
не нужно.(substr($str, 0, strlen($prefix)) == $prefix)
из принятого ответа было больше похоже наВот.
$array = explode("_", $string); if($array[0] == "bla") array_shift($array); $string = implode("_", $array);
источник
_
. Есть общая версия?Вот еще более быстрый подход:
// strpos is faster than an unnecessary substr() and is built just for that if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));
источник
Я думаю, что substr_replace делает то, что вы хотите, где вы можете ограничить замену частью своей строки: http://nl3.php.net/manual/en/function.substr-replace.php (Это позволит вам смотреть только на начало строки.)
Вы можете использовать параметр count str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ), это позволит вам ограничить количество замен, начиная слева, но это не будет заставлять это быть в начале.
источник
substr_replace
заменит символы в заданном диапазоне независимо от того, хотите ли вы удалить префикс или что-то еще. OP хочет удалить,bla_
«только если он находится в начале строки».Общая версия:
$parts = explode($start, $full, 2); if ($parts[0] === '') { $end = $parts[1]; } else { $fail = true; }
Некоторые тесты:
<?php $iters = 100000; $start = "/aaaaaaa/bbbbbbbbbb"; $full = "/aaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee"; $end = ''; $fail = false; $t0 = microtime(true); for ($i = 0; $i < $iters; $i++) { if (strpos($full, $start) === 0) { $end = substr($full, strlen($start)); } else { $fail = true; } } $t = microtime(true) - $t0; printf("%16s : %f s\n", "strpos+strlen", $t); $t0 = microtime(true); for ($i = 0; $i < $iters; $i++) { $parts = explode($start, $full, 2); if ($parts[0] === '') { $end = $parts[1]; } else { $fail = true; } } $t = microtime(true) - $t0; printf("%16s : %f s\n", "explode", $t);
На моем довольно старом домашнем ПК:
Выходы:
strpos+strlen : 0.158388 s explode : 0.126772 s
источник
Это удалит первое совпадение, где бы оно ни было, то есть начало, середину или конец.
$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));
источник
<?php $str = 'bla_string_bla_bla_bla'; echo preg_replace('/bla_/', '', $str, 1); ?>
источник
str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
теперь делает то, что вы хотите.
$str = "bla_string_bla_bla_bla"; str_replace("bla_","",$str,1);
источник
str_replace()
что$count
параметром функции будет переменная, переданная по ссылке и содержащая количество найденных замен, а не ограничение количества замен.Удалите www. от начала строки, это самый простой способ (ltrim)
$a="www.google.com"; echo ltrim($a, "www.");
источник
ltrim($a, "w.");
будет выполнять работу только в том случае, если домен не начинается с буквы «w».ltrim ('m.google.com', ".omg")
приводит кle.com
.ltrim
, он используется неправильно. второй параметр - это список символов, которые следует обрезать; поэтому одного"w."
будет достаточно.