views:

344

answers:

3
$url = "example-com--folder";
$searchArray = array('/-/','/--/');
$replaceArray = array('.','/');
$url = preg_replace($searchArray, $replaceArray, $url);

The output I want is example.com/folder but all I get now is example.com..folder

I know this is because I don't have the proper regex pattern, but what would that pattern be?

A: 

This is PHP, right?

You need a quantifier to specify that you want exactly two hyphens in the second pattern. Try:

$searchArray = array('/-/','/-{2}/');

The curly braces say 'require exactly n of the preceding pattern'

Here's a good reference.

Val
I don't even think his syntax is valid, complains because there are no regex delimiters.
meder
yeah, I think you're right -- I don't have a PHP interpreter at hand at the moment, so didn't bother with whether the function calls work -- I just concentrated on the regex pattern itself. It must work to some degree, tho, as he's getting *some* output...
Val
Thanks, meder, I added delimiters to my answer. Good catch!
Val
The curly bracket part works with single replacements but not with multiple replacement as in my code.
Chad
`/-{2}/` is equivalent to `/--/`
outis
@outis -d'oh, you're right. never mind!
Val
A: 

See if this works:

$url = "example-com--folder";
$searchArray = array('([^-])-([^-])','--');
$replaceArray = array('$1.$2','/');
$url = preg_replace("$searchArray", "$replaceArray", $url);

what this says is "match any - that doesn't have a dash before or after and replace that with a ." and "match double -- with /". obviously, you can extend this to limit the second match to 2 dashes only by adding ([^-]) at the from and back. as it is, "-----" will become "//", which you may not want.

saleemshafi
+2  A: 

Change the order of the '/--/' and '/-/' patterns so that '/--/' is checked first, otherwise '/-/' will trump '/--/'. Don't interpolate the arrays in the call to preg_replace.

$url = "example-com--folder";
$searchArray = array('/--/', '/-/');
$replaceArray = array('/', '.');
$url = preg_replace($searchArray, $replaceArray, $url);

Alternatives:

  • Use multiple calls to preg_replace in the order you wish to evaluate the REs. This isn't as objectionable as you might think because preg_replace loops over the arrays and handles each RE in turn.
  • Use an evaluated replacement

    $url = "www-example-com--folder";
    $replacements = array('-' => '.', '--' => '/');
    $url = preg_replace('/(--?)/e', '$replacements["$1"]', $url);
    
  • Use a lookahead and lookbehind

    $url = "www-example-com--folder";
    $searchArray = array('/(?<!-)-(?!-)/', '/--/');
    $replaceArray = array('.', '/');
    $url = preg_replace($searchArray, $replaceArray, $url);
    
outis
This works but it would be great if it were not dependent on the order of the array items.
Chad
You could just use two replacement invocations and get it over with.
meder
Thank you for all the suggestion. For now I will user your first suggestion (change order), and if I need to, I'll go back to doing multiple invocations as meder mentioned.
Chad