Adam Kiss
Adam Kiss

Reputation: 11859

Replacing multiple `-` with one `-` without regexp

I've seen so many misuses of RegExp, I don't really like it :)

I have string (as a result of two str_replaces) that might look something like this:

.?This iš my ".stRiNg."!
          |
          V
--this-is-my---string---

Is there any way better than

$string = trim(preg_replace('/[-]+/u','-', $string),'-');

to get:

this-is-my-string

?

Upvotes: 1

Views: 238

Answers (7)

maček
maček

Reputation: 77778

preg_replace() wins

<?php

function benchmark($callback){
  echo sprintf('%-30s: ', $callback);
  $t = microtime(true);
  foreach(range(1, 10000) as $n){
    call_user_func($callback);
  }
  echo (microtime(true)-$t)."\n";
}

function implode_explode_filter(){
  implode('-', array_filter(explode('-', '--this-is-my---string---')));
}

function preg_replace_trim(){
  preg_replace('/-+/', '-', trim('--this-is-my---string---', '-'));
}

function brant(){
  $parts = explode("-",'--this-is-my---string---');
  for($i=0;$i<count($parts);$i++) {
      if (strlen($parts[$i]) < 1) {
          unset($parts[$i]);
      }
  }
  reset($parts);
  $string = implode("-",$parts);
}

function murze_bisko(){
  $string = "--this-is-my---string---";
  while (strpos($string, "--") !== false) {
    $string = str_replace("--", "-", $string);
  }
  $string = trim($string, '-'); # both of their answers were broken until I added this line
}

benchmark('implode_explode_filter');
benchmark('preg_replace_trim');
benchmark('brant');
benchmark('murze_bisko');

# Output
# implode_explode_filter        : 0.062376976013184
# preg_replace_trim             : 0.038193941116333
# brant                         : 0.11686086654663
# murze_bisko                   : 0.058025121688843
?>

Upvotes: 8

bisko
bisko

Reputation: 4078

Just for the sake of the competition:

$string = str_replace('--','-', str_replace('--','-', '--this-is-my---string---'));

This is the fastest way to do it. It first replaces double -- with single and then cleans the rest again, so only single - remain.

Upvotes: 0

murze
murze

Reputation: 4103

So you want to go from

--this-is-my---string---

to

this-is-my-string?

The best way would be a reg exp, but if you want a simple solution in php you can use

$string = "--this-is-my---string---";
while (! strpos($string, "--") === false) {
  $string = str_replace("--", "-", $string);
}

After the loop $string will contain the result.

Upvotes: 0

vicvicvic
vicvicvic

Reputation: 6234

A better way? Probably not. Another way? Yes (essentially one-line version of Brant's answer):

implode('-', array_filter(explode('-', $string), function($s) { return strlen($s); }));

Note that you can't just use the naked array_filter reliably, because !!"0" == false in PHP.

Upvotes: 1

fuxia
fuxia

Reputation: 63556

print implode('-', array_filter( explode( '-', $string) ) );

Easy. :)

Upvotes: 4

Brant Messenger
Brant Messenger

Reputation: 1451

$parts = explode("-",'--this-is-my---string---');
for($i=0;$i<count($parts);$i++) {
    if (strlen($parts[$i]) < 1) {
        unset($parts[$i]);
    }
}
reset($parts);
$string = implode("-",$parts);

Upvotes: 0

GSto
GSto

Reputation: 42350

I don't understand why you are looking for a 'better' way. Your way uses a simple regex in a place where it's perfectly appropriate to do so. What could be better than that?

Upvotes: 5

Related Questions