Reputation: 1108
I have a regular expression
(?<=\w)([A-Z]|_|\s)
That matches against the following correctly
ModelName (matches N)
modelName (matches N)
Model Name (matches space)
model name (matches space)
model_name (matches underscore)
but the following is incorrect
Model_Name (matches underscore and N)
In the latter, I need to only match the space, but have the same regexp matches on all the previous results.
I'm a little rusty, so does anyone know how to best achieve this?
My context is as follows:
/**
* Converts 'ModelName', 'modelName' and 'model_name' to 'model-name'
* @param string $word
* @return string
*/
public static function hyphenate($word)
{
return strtolower(str_replace([' ', '_'], '', preg_replace('!(?<=\\w)([A-Z]|_|\\s)!', '-$1', $word)));
}
The last failing match will make this function return model--name
.
Would it be easier to just do another str_replace('--', '', $word) before returning?
Upvotes: 2
Views: 55
Reputation: 9644
To do it all in one step you can use
preg_replace('/(?<=[a-zA-Z])(?:([A-Z])|[_\h])/', '-\1', $string);
See demo here.
The idea is to capture the uppercase letter in first capturing group, which will then be empty if you match a _
or \h
(horizontal whitespace).
Your issue was that \w
stands for [a-zA-Z_]
, so the look behind matched _
as well.
Upvotes: 6