Regex replace all matches if the match is not at the end of the string

I am currently using this regex to replace all non-abelian numeric characters from a string and replace them with a dash

$newString = preg_replace("/[^a-z0-9.]+/i", "-", $string);

      

This one works great for the next line.

$string = "this will work fine";
$newString = "this-will-work-fine";

      

But , if the string has a non-alpha numeric, as the final character, it will match and replace it, as one would suspect.

$string = "How can I fix this?";
$newString = "How-can-I-fix-this-";

      

How can I improve this regex to have the following output?

$newString = "How-can-I-fix-this";

      

Regular expression should work in cases . I know I can just trim the string using a separate function, but ideally I would like to use a single regex. Is it possible?

+3


source to share


5 answers


Since you are using PHP, you can define multiple patterns and replacements in one go. Here's a quick demo:

$string = "How can I fix this?";
$patterns = array('/[^0-9a-z.]+/i', '/[^0-9a-z.]+(?=$)/i');
$replacements = array('-', '');

echo preg_replace($patterns, $replacements, $string) . "\n";

      

which prints:



How-can-I-fix-this

In fact, these are no more than two consecutive replacements:

$string = "How can I fix this?";

echo preg_replace('/[^0-9a-z.]+/', '-', preg_replace('/[^0-9a-z.]+$/', '', $string)) . "\n";

      

+5


source


I think you need to do it in two steps, because you have two different cases: at the beginning and in the middle of a line, you want to replace non alphanumerics with "-". At the end, you want to replace them with an empty string.



+2


source


You can always trim("-how-can-i-fix-this-", "-");

.

+1


source


Actually, this can be done in a single regex:

$newString = preg_replace('/[^a-z0-9.]++([a-z0-9.]++)(?:[^a-z0-9.]++$)?/i', '-$1', $string);

Note:

  • For future reference '-\1'

    , '-\\1'

    , "-\\1"

    and "-$1"

    all valid alternatives to replace the line.
  • Possessive quantifiers are not needed in this case. However, I always use them, even when the speed improvement is minor.

EDIT:

The third case (where the first character is not literal) can also be done with a single regex:

$newString = preg_replace('/(?:^[^a-z0-9.]++([a-z0-9.]++))?[^a-z0-9.]++([a-z0-9.]++)(?:[^a-z0-9.]++$)?/i', '$1-$2', $string);

+1


source


$string = 'How can I fix this?';
$string = trim(preg_replace('/[^A-Za-z0-9]/', '-', $string), '-'); 

      

Replace all non-alphanumeric characters with '-'

and then draw them from the end.

0


source







All Articles