Регулярное выражение, замените несколько косых черт только одной

Кажется, что решить эту проблему легко, но это не так просто, как кажется. У меня есть эта строка в PHP:

////%postname%/

Это URL-адрес, и я никогда не хочу использовать более одной косой черты подряд. Я никогда не хочу полностью удалять косые черты.

Вот как это должно выглядеть:

/%postname%/

Поскольку структура может выглядеть по-другому, я думаю, мне нужна умная preg заменить регулярное выражение. Он должен работать с URL-адресами следующим образом:

////%postname%//mytest/test///testing

который должен быть преобразован в это:

/%postname%/mytest/test/testing

person Jens Törnell    schedule 07.02.2010    source источник


Ответы (6)


Ну вот:

$str = preg_replace('~/+~', '/', $str);

Or:

$str = preg_replace('~//+~', '/', $str);

Или даже:

$str = preg_replace('~/{2,}~', '/', $str);

Простой str_replace() также поможет (если не более двух последовательных косых черт):

$str = str_replace('//', '/', $str);
person Alix Axel    schedule 07.02.2010
comment
Гораздо короче, чем ожидалось. Я не мог заставить его потерпеть неудачу. Спасибо! - person Jens Törnell; 07.02.2010
comment
str_replace так не пойдет. я считаю, что вам нужна рекурсивная функция. (посмотрите ниже) - person Gal; 07.02.2010
comment
Как говорит Гал, str_replace не будет работать, если косой черты больше двух. Preg_replace будет работать, но версия Барта К. лучше, потому что она не соответствует одиночным косым чертам, а только двум или более. - person meouw; 07.02.2010
comment
@meouw: Спасибо, я сомневался в этом - теперь исправлено. - person Alix Axel; 07.02.2010

Пытаться:

echo preg_replace('#/{2,}#', '/', '////%postname%//mytest/test///testing');
person Bart Kiers    schedule 07.02.2010

function drop_multiple_slashes($str)
{
  if(strpos($str,'//')!==false)
  {
     return drop_multiple_slashes(str_replace('//','/',$str));
  }
  return $str;
}

это использует str_replace

person Gal    schedule 07.02.2010
comment
Это не сработает, если вы не измените !== 0 на !== false. Кроме того, нет необходимости в рекурсии: while (strpos($str, '//') !== false) { $str = str_replace('//', '/', $str); } вернуть $str; - person GZipp; 07.02.2010
comment
@GZipp, ты прав, я отредактировал. Насколько я знаю, нет никакой разницы в производительности между рекурсивной функцией и циклом while (но я бы с удовольствием доказал обратное). - person Gal; 08.02.2010

Поздно, но все эти методы также удалят косую черту http://, но это.

function to_single_slashes($input) {
    return preg_replace('~(^|[^:])//+~', '\\1/', $input);
}

# out: http://localhost/lorem-ipsum/123/456/
print to_single_slashes('http:///////localhost////lorem-ipsum/123/////456/');
person K-Gun    schedule 30.03.2014

Мое решение:

while (strlen($uri) > 1 && $uri[0] === '/' && $uri[1] === '/') {
    $uri = substr($uri, 1);
}
person Thomas Decaux    schedule 05.03.2016

person    schedule
comment
Нет, это заменит '////' на '//', хотя здесь нужна косая черта. - person Bart Kiers; 07.02.2010