PHP Preg-Replace более одного подчеркивания

Как мне с помощью preg_replace заменить более одного подчеркивания только одним подчеркиванием?

9 ответов

Решение

preg_replace('/[_]+/', '_', $your_string);

+ Оператор сопоставляет несколько экземпляров последнего символа (или группы захвата).

$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.

preg_replace()

нужен оператор +

$text = "______";
$text = preg_replace('/[_]+/','_',$text);

Вы также можете использовать библиотеку 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);
Другие вопросы по тегам