PHP Preg-Replace более одного подчеркивания
Как мне с помощью preg_replace заменить более одного подчеркивания только одним подчеркиванием?
9 ответов
+
Оператор сопоставляет несколько экземпляров последнего символа (или группы захвата).
$string = preg_replace('/_+/', '_', $string);
На самом деле используя /__+/
или же /_{2,}/
будет лучше чем /_+/
поскольку одно подчеркивание не нуждается в замене. Это улучшит скорость preg варианта.
Запустив тесты, я нашел это:
while (strpos($str, '__') !== false) {
$str = str_replace('__', '_', $str);
}
чтобы быть последовательно быстрее, чем это:
$str = preg_replace('/[_]+/', '_', $str);
Я сгенерировал тестовые строки различной длины с этим:
$chars = array_merge(array_fill(0, 50, '_'), range('a', 'z'));
$str = '';
for ($i = 0; $i < $len; $i++) { // $len varied from 10 to 1000000
$str .= $chars[array_rand($chars)];
}
file_put_contents('test_str.txt', $str);
и протестирован с этими сценариями (запускаются отдельно, но на одинаковых строках для каждого значения $ len):
$str = file_get_contents('test_str.txt');
$start = microtime(true);
$str = preg_replace('/[_]+/', '_', $str);
echo microtime(true) - $start;
а также:
$str = file_get_contents('test_str.txt');
$start = microtime(true);
while (strpos($str, '__') !== false) {
$str = str_replace('__', '_', $str);
}
echo microtime(true) - $start;
Для более коротких строк метод str_replace() был на 25% быстрее, чем метод preg_replace(). Чем длиннее строка, тем меньше разница, но str_replace() всегда был быстрее.
Я знаю, что некоторые предпочитают один метод другому по причинам, отличным от скорости, и я был бы рад прочитать комментарии, касающиеся результатов, метода тестирования и т. Д.
Для всех, кого привлекает ответ @GZipp по причинам тестирования / микроптимизации, я думаю, что следующий цикл после тестирования должен выполняться немного лучше, чем предварительный тест.
while()
цикл, потому что
strpos()
звонок был удален.
str_replace()
имеет параметр ссылочной переменной, который можно использовать для разрыва цикла без дополнительного повторного вызова функции. Конечно, он всегда будет пытаться выполнить хотя бы одну замену и не остановится, пока не пройдёт строку без замен.
Код: (Демо)
$str = 'one_two__three___four____bye';
do {
$str = str_replace('__', '_', $str, $count);
} while ($count);
var_export($str);
// 'one_two_three_four_bye'
Что касается, то вот пара хороших вариантов:
echo preg_replace('/_{2,}/', '_', $str);
echo preg_replace('/_\K_+/', '', $str); // \K forgets the first, remembers the rest
Я не рекомендую использовать
+
потому что он делает ненужные замены (чтобы
_
)
echo preg_replace('/_+/', '_', $str);
Определенно нет никакой пользы от использования символьного класса
или /[_]+/
./[_]{2,}/
The benefit of using
preg_replace()
is that the string is never traversed more than once. This makes it a very direct and appropriate tool.
Вы также можете использовать библиотеку T-Regx, которая имеет автоматические разделители.
pattern('_+')->replace($your_string)->with('_');
This will Accept Only Characters,numeric value or Special Character found it will replace with _
<?php
error_reporting(0);
if($_REQUEST)
{
PRINT_R("<PRE>");
PRINT_R($_REQUEST);
$str=$_REQUEST[str];
$str=preg_replace('/[^A-Za-z\-]/', '_', $str);
echo strtolower(preg_replace('/_{2,}/','_',$str));
}
?>
<form action="" method="post">
<input type="text" name="str"/>
<input type="submit" value="submit"/>
</form>
Я не причина, по которой вы хотите использовать preg_replace, но что не так с:
str_replace('__', '_', $string);