Get the first letter of each word in a string

PhpString

Php Problem Overview


How would I get the first letter of each word for a given string?

$string = "Community College District";
$result = "CCD";

I found the javascript method but wasn't sure how to convert it to php.

Php Solutions


Solution 1 - Php

explode() on the spaces, then you use the [] notation to access the resultant strings as arrays:

$words = explode(" ", "Community College District");
$acronym = "";

foreach ($words as $w) {
  $acronym .= $w[0];
}

If you have an expectation that multiple spaces may separate words, switch instead to preg_split()

$words = preg_split("/\s+/", "Community College District");

Or if characters other than whitespace delimit words (-,_) for example, use preg_split() as well:

// Delimit by multiple spaces, hyphen, underscore, comma
$words = preg_split("/[\s,_-]+/", "Community College District");

Solution 2 - Php

The best way to accomplish this is with regular expressions.

Lets break down what you want in a logical way: You want every character from the string is at the beginning of a word. The best way to identify those characters is to look for those characters that are preceded by white space.

So we start with a lookbehind for that space character, followed by any character:

/(?<=\s)./

This will find any character preceded by a space. But - the first character in the string is a character in the string is one you want extract. And because it's the first character in the string, it can't be preceded by a space. So we want to match anything preceded by a space or the first character in the string, so we add a start-of-subject assertion:

/(?<=\s|^)./

Now we are getting closer. But what if the string contains blocks of multiple spaces? What if it contains a space followed by a punctuation character? We probably don't want to match any of those, in fat we probably just want to match letters. We can do that with a character class [a-zA-Z]. And we can make are expression case-insensitive using the i modifier.

So we end up with:

/(?<=\s|^)[a-z]/i

But how do we actually use this in PHP? Well we want to match all occurrences of the regular expression within the string so we use (you guessed it) preg_match_all():

$string = "Progress in Veterinary Science";

$expr = '/(?<=\s|^)[a-z]/i';
preg_match_all($expr, $string, $matches);

Now we have all the characters we wanted to extract. To construct the result string you show, we need to join them together again:

$result = implode('', $matches[0]);

...and we need to ensure that they are all upper-case:

$result = strtoupper($result);

And that's really all there is to it.

See it working


Here's a slightly compressed version, using the alternative regex from Leigh's comment to "capture the initial letters of words separated by hyphens, full stops, etc." (rather than only spaces.)

$str="Foo Bar";
preg_match_all('/(?<=\b)[a-z]/i',$str,$matches);
$result=strtoupper(implode('',$matches[0]));

Solution 3 - Php

Assuming the words are all split by spaces, this is a suitable solution:

$string = "Progress in Veterinary Science";

function initials($str) {
    $ret = '';
    foreach (explode(' ', $str) as $word)
        $ret .= strtoupper($word[0]);
    return $ret;
}

echo initials($string); // would output "PIVS"

Solution 4 - Php

There are a lot of explode answers. I think using the strtok function is a much more elegant and memory-efficient solution:

function createAcronym($string) {
    $output = null;
    $token  = strtok($string, ' ');
    while ($token !== false) {
        $output .= $token[0];
        $token = strtok(' ');
    }
    return $output;
}
$string = 'Progress in Veterinary Science';
echo createAcronym($string, false);

Here is a more robust and useful function, which supports UTF8 characters and the option to only use the capitalized words:

function createAcronym($string, $onlyCapitals = false) {
    $output = null;
    $token  = strtok($string, ' ');
    while ($token !== false) {
        $character = mb_substr($token, 0, 1);
        if ($onlyCapitals and mb_strtoupper($character) !== $character) {
            $token = strtok(' ');
            continue;
        }
        $output .= $character;
        $token = strtok(' ');
    }
    return $output;
}
$string = 'Leiðari í Kliniskum Útbúgvingum';
echo createAcronym($string);

Solution 5 - Php

Michael Berkowski's (and others) answer, simplified to one line and working correctly on multi-byte characters (i.e. making abbreviation / initials out of non-Latin string):

foreach(explode(' ', $words) as $word) $acronym .= mb_substr($word, 0, 1, 'utf-8');

Using mb_substr($word, 0, 1, 'utf-8'), instead of $word[0] seems to be must, if you're working on non-Latin, multi-byte strings and characters, i.e. when using UTF-8 encoded strings.

Solution 6 - Php

As explained by others, classical way consist in iterating over each word of your initial string, reduce the word to its first letter, and combine those first letters together.

Here is a helper method combining the different steps.

/**
 * @return string
 */
function getInitials($string = null) {
    return array_reduce(
        explode(' ', $string),
        function ($initials, $word) {
            return sprintf('%s%s', $initials, substr($word, 0, 1));
        },
        ''
    );
}

NB : this will return an empty string in case the given string is empty.

getInitials('Community College District') > string 'CCD' (length=3)

getInitials() > string '' (length=0)

getInitials('Lorem ipsum dolor sic amet') > string 'Lidsa' (length=5)

Of course you can add filters to the callback function of array_reduce(), such as strtoupper() if you prefer only uppercased initials for instance.

Solution 7 - Php

$temp = explode(' ', $string);
$result = '';
foreach($temp as $t)
    $result .= $t[0];

Solution 8 - Php

Like this

preg_match_all('#(?<=\s|\b)\pL#u', $String, $Result);
echo '<pre>' . print_r($Result, 1) . '</pre>';

Solution 9 - Php

$str = 'I am a String!';
echo implode('', array_map(function($v) { return $v[0]; }, explode(' ', $str)));

// would output IaaS

Solution 10 - Php

Something I've cooked up.

/**
 * Return the first letter of each word in uppercase - if it's too long.
 *
 * @param string $str
 * @param int $max
 * @param string $acronym
 * @return string
 */
function str_acronym($str, $max = 12, $acronym = '')
{
    if (strlen($str) <= $max) return $str;

    $words = explode(' ', $str);

    foreach ($words as $word)
    {
        $acronym .= strtoupper(substr($word, 0, 1));
    }

    return $acronym;
}

Solution 11 - Php

function acronym( $string = '' ) {
    $words = explode(' ', $string);
    if ( ! $words ) {
        return false;
    }
    $result = '';
    foreach ( $words as $word ) $result .= $word[0];
    return strtoupper( $result );
}

Solution 12 - Php

Why not using the str_word_count function for this?

  1. get each word as a row in an array

  2. reduce that array to the first letter

    $acronym = array_reduce( str_word_count("Community College District", 1), function($res , $w){ return $res . $w[0]; } );

Solution 13 - Php

Assuming that the original string is properly built (trimmed and without double spaces), this is what I do:

$name = 'John Doe';
$initials = implode( '', array_map( function ( $part ) { 
    return strtoupper( $part['0'] );
}, explode( ' ', $name ) ) );

Basically, breaking the string into words, extracting & capitalizing the first character of a word, and gluing them back together.

Solution 14 - Php

I think you have to explode and join them back again .....

<?php
$string  = "Progress in Veterinary Science";
$pieces = explode(" ", $string);
$str="";
foreach($pieces as $piece)
{
    $str.=$piece[0];
}    
echo $str; /// it will result into  "PiVS"
?>

Solution 15 - Php

Using Prateeks foundation, here's a simple example with explanations

//  initialize variables
$string = 'Capitalize Each First Word In A String';
$myCapitalizedString = '';

//  here's the code
$strs=explode(" ",$string);    
foreach($strs as $str) {
  $myCapitalizedString .= $str[0]; 
}

//  output
echo $myCapitalizedString;  // prints 'CEFWIAS'

Solution 16 - Php

If there are more number of spaces between two letters in the input string then try this.

function first_letter($str)
{
	$arr2 = array_filter(array_map('trim',explode(' ', $str)));
	$result='';
	foreach($arr2 as $v)
	{
		$result.=$v[0];
	}
	return $result;
}

$str="    Let's   try   with    more   spaces       for  fun .   ";

echo first_letter($str);

Demo1

Alternative of same code

function first_letter($str)
{
	return implode('', array_map(function($v) { return $v[0]; },array_filter(array_map('trim',explode(' ', $str)))));;
}

$str="    Let's   try   with    more   spaces       for  fun .   ";

echo first_letter($str);

Demo2

Solution 17 - Php

Here's a function that gets you the initials of a name and if the initials are only 1 letter then it returns the first 2 letters of the first name.

function getNameInitials($name) {

	preg_match_all('#(?<=\s|\b)\pL#u', $name, $res);
	$initials = implode('', $res[0]);

	if (strlen($initials) < 2) {
		$initials = strtoupper(substr($name, 0, 2));
	}

	return strtoupper($initials);
}

Solution 18 - Php

Try this-

$strs=explode(" ",$string);

foreach($strs as $str)
  echo $str[0];

Solution 19 - Php

<?php $arr = explode(" ",$String);

foreach($arr as $s)
{
   echo substr($s,0,1);
}

?>

firstly I explode string by spaces then I substr first char.

http://php.net/substr

http://php.net/explode

Solution 20 - Php

Something like this should do the trick :

$string = 'Some words in a string';
$words = explode(' ', $string); // array of word
foreach($words as $word){
    echo $word[0]; // first letter
}

Solution 21 - Php

For the case that you'll be doing this on large strings (or even directly from file) explode() isn't the best way to do this. Imagine how much memory will get wasted if you have to split string 2MB large into memory.

With little more coding and (assuming PHP >= 5.0) you can easily implement PHP's Iterator class that will do exactly this. This will be close to generator in python and long story short, here's the code:

/**
 * Class for CONTINOUS reading of words from string.
*/
class WordsIterator implements Iterator {
    private $pos = 0;
    private $str = '';
    private $index = 0;
    private $current = null;
    
    // Regexp explained:
    // ([^\\w]*?) - Eat everything non-word before actual word characters
    //				Mostly used only if string beings with non-word char
    // ([\\w]+)	  - Word
    // ([^\\w]+?|$) - Trailing thrash
    private $re = '~([^\\w]*?)([\\w]+)([^\\w]+?|$)~imsS';

	// Primary initialize string
    public function __construct($str) {
        $this->str = $str;
    }

	// Restart indexing
    function rewind() {
        $this->pos = 0;
        $this->index = 0;
        $this->current = null;
    }

	// Fetches current word
    function current() {
        return $this->current;
    }

	// Return id of word you are currently at (you can use offset too)
    function key() {
        return $this->index;
    }
	
	// Here's where the magic is done
    function next() {
    	if( $this->pos < 0){
    		return;
    	}
    	
 	    $match = array();
        ++$this->index;
        
        // If we can't find any another piece that matches... Set pos to -1
        // and stop function
        if( !preg_match( $this->re, $this->str, $match, 0, $this->pos)){
            $this->current = null;
        	$this->pos = -1;
        	return;
        }
        
        // Skip what we have read now
        $this->current = $match[2];
        $this->pos += strlen( $match[1]) + strlen( $match[2]) + strlen($match[3]);
        
        // We're trying to iterate past string
        if( $this->pos >= strlen($this->str)){
        	$this->pos = -1;
        }
        
    }

	// Okay, we're done? :)
    function valid() {
        return ($this->pos > -1);
    }
}

And if you'll use it on a bit more challenging string:

$a = new WordsIterator("Progress in Veterinary Science. And, make it !more! interesting!\nWith new line.");
foreach( $a as $i){
	echo $i;
	echo "\n";
}

Will you get the expected result:

Progress
in
Veterinary
Science
And
make
it
more
interesting
With
new
line

So you can easily use $i[0] to fetch first letter.You probably can see that this is more effective solution than splitting whole string into memory (always use only as little memory as possible). You also could easily modify this solution to work with continuous reading of files etc.

Solution 22 - Php

Try This

function initials($string) {
		if(!(empty($string))) {
			if(strpos($string, " ")) {
				$string = explode(" ", $string);
				$count = count($string);
				$new_string = '';
				for($i = 0; $i < $count; $i++) {
				$first_letter = substr(ucwords($string[$i]), 0, 1);
				$new_string .= $first_letter;
			}
			return $new_string;
			} else {
				$first_letter = substr(ucwords($string), 0, 1);
				$string = $first_letter;
				return $string;
			}
		} else {
			return "empty string!";
		}
	}
	echo initials('Thomas Edison');

Solution 23 - Php

I like Reg Expression over any other method of string extraction, but if you are unfamiliar with Reg Ex then hear is a method using the explode() PHP function:

$string = "David Beckham";
$string_split = explode(" ", $string);
$inititals = $string_split[0][0] . $string_split[1][0];
echo $inititals;

Obviously the above code will only work on a name containing two words.

Solution 24 - Php

This answer https://stackoverflow.com/a/33080232/1046909 but with multibyte strings support:

if (!function_exists('str_acronym')) {
    function str_acronym(string $str, int $min = -1, string $prefix = null): string
    {
        if (mb_strlen($str) <= $min) {
            return $str;
        };

        $words = explode(' ', $str);

        $acronym = strval($prefix);

        foreach ($words as $word) {
            if ($word = trim($word)) {
                $acronym .= mb_strtoupper(mb_substr($word, 0, 1));
            }
        }

        return $acronym;
    }
}

Solution 25 - Php

You can use that function based on the accepted answer from @Michael Berkowski

function buildAcronym($string, $length = 1) {
    $words = explode(" ", $string);
    $acronym = "";
    $length = (self::is_empty($string) || $length <= 0 ? 1 : $length);

    foreach ($words as $i => $w) {
        $i += 1;
        if($i <= $length) {
            $acronym .= $w[0];
        }
    }

    return $acronym;
}

The $length parameter determines how many chars you want to display

USAGE:

$acronym = buildAcronym("Hello World", 2);

Solution 26 - Php

I'm a little underwhelmed by the suggested techniques here (despite having so many to choose from).

Assuming your input string is solely composed of whitespace delimited "words" (and you don't need to validate that the first character of each word is an actual letter), you can use this concise, multibyte safe technique to trim all letters after the first letter from each word and also discard the delimiting whitespaces.

Code: (Demo)

$string = "Let's observe obviously knowledgeable approaches that target helpful items succinctly";

echo preg_replace('~\S\K\S*\s*~u', '', $string);

Output:

Lookatthis

If you want to specifically target "letters", you can use \p{Ll} and non-letters with \P{Ll} (as replacements for \S and \s. The \K restarts the fullstring match -- by effect, the matched first matched letter of each word is "set free" before matching more characters to be replaced by the empty string.


I see some other approaches on this page that are using lookbehinds to match the first letter of each word with preg_match_all('~(?<=\s|\b)\pL~u', ...), but notice the effect on fringe cases:

$string = "Let's check some fringe-cases: like @mentions and email@example";
#matches:  ^   ^ ^     ^    ^      ^      ^     ^        ^   ^     ^

I cannot say if these would be desirable results, but if they were, then the pattern could be distilled to ~\b\pL~u because the word boundary (\b) is a zero-length assertion that doesn't require a lookbehind AND it covers every character that \s could match.


I should also mention that any of the answers on this page that are accessing the first character by its offset (using array-like syntax like $word[0]) or substr() will fail whenever a multibyte character is encountered.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGrigorView Question on Stackoverflow
Solution 1 - PhpMichael BerkowskiView Answer on Stackoverflow
Solution 2 - PhpDaveRandomView Answer on Stackoverflow
Solution 3 - PhpcasrafView Answer on Stackoverflow
Solution 4 - PhpSverri M. OlsenView Answer on Stackoverflow
Solution 5 - PhptrejderView Answer on Stackoverflow
Solution 6 - PhpFlo SchildView Answer on Stackoverflow
Solution 7 - PhpAschererView Answer on Stackoverflow
Solution 8 - PhpWinstonView Answer on Stackoverflow
Solution 9 - PhpbillyonecanView Answer on Stackoverflow
Solution 10 - Phpuser5134807View Answer on Stackoverflow
Solution 11 - PhpsmasseyView Answer on Stackoverflow
Solution 12 - PhpSpirView Answer on Stackoverflow
Solution 13 - PhpHike NalbandyanView Answer on Stackoverflow
Solution 14 - PhpRavindra ShekhawatView Answer on Stackoverflow
Solution 15 - PhpRob StockiView Answer on Stackoverflow
Solution 16 - PhpDurgesh TiwariView Answer on Stackoverflow
Solution 17 - PhpSalamView Answer on Stackoverflow
Solution 18 - PhpPrateek ShuklaView Answer on Stackoverflow
Solution 19 - PhpRobertView Answer on Stackoverflow
Solution 20 - PhpMarshallView Answer on Stackoverflow
Solution 21 - PhpVyktorView Answer on Stackoverflow
Solution 22 - PhpSanView Answer on Stackoverflow
Solution 23 - PhpMatt JamesonView Answer on Stackoverflow
Solution 24 - PhpMingalevMEView Answer on Stackoverflow
Solution 25 - PhpJ0rdAnView Answer on Stackoverflow
Solution 26 - PhpmickmackusaView Answer on Stackoverflow