separate string in each capital letter or number

0

I need to separate a string with "_" every time it finds a capital letter and transform it to lowercase. This to separate each word from the class name, for example if I have the following class:

class UserNote{
}

the name of that class would look like: user_notes

I did this method but it only works when the class has 1 word:

public function parseClassName(){
    $className = strtolower(get_class($this));
    return $className . 's';
}

SOLVED:

Thanks guys, I've tried both answers and both work correctly. My method has stayed that way for each of the answers.

public function parseClassName(){
    $className = preg_replace('/\s+/u', '', ucwords(get_class($this)));
    $className = mb_strtolower(preg_replace('/(.)(?=[A-Z])/u', '$1_', $className));
    return $className . 's';
}

The other method:

public function parseClassName(){

    $className = preg_replace('/(?<=\w)(\p{Lu})/u', '_$1', get_class($this));
    $className = mb_strtolower($className);
    return $className . 's';
}

Thanks again.

    
asked by kmilo93sd 13.03.2018 в 18:32
source

2 answers

2

For the underscore you can use preg_replace , according to the documentation:

  

replacement can contain references of the form \\ n or $ n, the last form being preferred. Each reference of this type will be replaced by the text captured by the n-like pattern in parentheses.

So we can use '_$1' as the value of replacement , and the regular expression /(?<=\w)(\p{Lu})/u , this way

echo mb_strtolower(preg_replace('/(?<=\w)(\p{Lu})/u', '_$1', 'UserNote'));

What will this print: user_note

To put it as a plural you must consider many things, such as irregular words, or the language. I think that for your example it would be enough to add s to the end that works for most of the cases, in this way:

$word = 'UserNote';
$underscore = mb_strtolower(preg_replace('/(?<=\w)(\p{Lu})/u', '_$1', $word));
$plural = $underscore . 's';

echo $plural;

Will print: user_notes .

What the regular expression does is to make sure that there is a word before so as not to put a _ at the beginning and catch everything that is a capital letter

    
answered by 13.03.2018 / 18:49
source
1

I'm going to collaborate with the code that Laravel uses to convert to snake_case , which is what this style is usually called, I adapt it slightly so that it works without the internal dependencies of the framework:

public function snake($value, $delimiter = '_')
{
    if (! ctype_lower($value)) {
        $value = preg_replace('/\s+/u', '', ucwords($value));
        $value = mb_strtolower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
    }

    return $value;
}

Here is the full source of this helper: link

    
answered by 13.03.2018 в 19:27