16

I'm looking for a way that I can extract the first letter of each word from an input field and place it into a variable.

Example: if the input field is "Stack-Overflow Questions Tags Users" then the output for the variable should be something like "SOQTU"

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
dmschenk
  • 379
  • 1
  • 5
  • 19

11 Answers11

25
$s = 'Stack-Overflow Questions Tags Users';
echo preg_replace('/\b(\w)|./', '$1', $s);

the same as codaddict's but shorter

  • For unicode support, add the u modifier to regex: preg_replace('...../u',
T.Todua
  • 53,146
  • 19
  • 236
  • 237
user187291
  • 53,363
  • 19
  • 95
  • 127
  • it's clever but needs a little explanation because it's not obvious : it searches for a word (can be 1 char only) preceded by a boundary OR any character. All characters of the string matches at least this second condition and thus is replaced by the content of the matching parenthesis : that is to say nothing in every case excepted for characters preceded by a boundary which are replaced by the character only and then initials become the only remaining chars. If you want to preserve blank space and separators like - replace (\w) by (\.) and then "Jean-Claude Vandamme" wil give "J-C V" – plancton Nov 25 '16 at 15:41
  • just realized it doesn't work with latin characters ..."Jean-Claude Vandàmme" wil give "J-C Vàm" @mark-baker 's solution works better if you work with most character sets – plancton Nov 25 '16 at 16:46
  • How would you do it so that it ignores the dash - Eg. SQTU is returned? – friek108 Feb 21 '19 at 23:37
21

Something like:

$s = 'Stack-Overflow Questions Tags Users';

if(preg_match_all('/\b(\w)/',strtoupper($s),$m)) {
    $v = implode('',$m[1]); // $v is now SOQTU
}

I'm using the regex \b(\w) to match the word-char immediately following the word boundary.

EDIT: To ensure all your Acronym char are uppercase, you can use strtoupper as shown.

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • Can this be modified to convert small text to capitals? – dmschenk Sep 09 '10 at 16:28
  • is this related to the current question or a different question? – codaddict Sep 09 '10 at 16:47
  • this is related to your code in this question. your code produces a small letter if that happens to be what the first letter of a word is. I'm just asking how I would convert those to capital letters... I guess it would be a different question. – dmschenk Sep 09 '10 at 16:59
  • Thanks for your help! I wish i was further along with php... I might have realized the answer was staring me right in the face. Thanks again – dmschenk Sep 09 '10 at 17:19
6

Just to be completely different:

$input = 'Stack-Overflow Questions Tags Users';

$acronym = implode('',array_diff_assoc(str_split(ucwords($input)),str_split(strtolower($input))));

echo $acronym;
Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • 1
    interesting that it picks up caps in the same word. that could certainly be useful. – dmschenk Sep 09 '10 at 16:38
  • That's a "side-effect" of the ucwords() function... makes it useful for capitalising double-barelled names – Mark Baker Sep 09 '10 at 21:14
  • 1
    Be careful : if the phrase contains only capitals, ilt will return the whole phrase. You should do this instead : `$acronym = implode('',array_diff_assoc(str_split(ucwords(strtolower($input))),str_split(strtolower($input))));` – plancton Nov 29 '16 at 10:09
5
$initialism = preg_replace('/\b(\w)\w*\W*/', '\1', $string);
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
4

If they are separated by only space and not other things. This is how you can do it:

function acronym($longname)
{
    $letters=array();
    $words=explode(' ', $longname);
    foreach($words as $word)
    {
        $word = (substr($word, 0, 1));
        array_push($letters, $word);
    }
    $shortname = strtoupper(implode($letters));
    return $shortname;
}
shamittomar
  • 46,210
  • 12
  • 74
  • 78
3

Regular expression matching as codaddict says above, or str_word_count() with 1 as the second parameter, which returns an array of found words. See the examples in the manual. Then you can get the first letter of each word any way you like, including substr($word, 0, 1)

Fanis Hatzidakis
  • 5,282
  • 1
  • 33
  • 36
2

The str_word_count() function might do what you are looking for:

$words = str_word_count ('Stack-Overflow Questions Tags Users', 1);
$result = "";
for ($i = 0; $i < count($words); ++$i)
  $result .= $words[$i][0];
Karel Petranek
  • 15,005
  • 4
  • 44
  • 68
2
function initialism($str, $as_space = array('-'))
{
    $str = str_replace($as_space, ' ', trim($str));
    $ret = '';
    foreach (explode(' ', $str) as $word) {
        $ret .= strtoupper($word[0]);
    }
    return $ret;
}

$phrase = 'Stack-Overflow Questions IT Tags Users Meta Example';
echo initialism($phrase);
// SOQITTUME
GZipp
  • 5,386
  • 1
  • 22
  • 18
  • This is pretty cool, it also had some benifits I hadn't initially thought of like converting small text to caps and the ability to easily control the separator markers used ('-','/',',')etc... – dmschenk Sep 09 '10 at 16:32
  • And all that without having to spend your otherwise-productive hours dithering with regular expressions. – GZipp Sep 10 '10 at 12:58
  • This line or something like it should be added inside the foreach: [I]if ($word && ctype_alnum($word[0]))[/I] (The cytpe test could be switchable with another optional argument.) And test, please. – GZipp Sep 10 '10 at 13:18
0
$s = "Stack-Overflow Questions IT Tags Users Meta Example";    
$sArr = explode(' ', ucwords(strtolower($s)));
$sAcr = "";
foreach ($sArr as $key) {
   $firstAlphabet = substr($key, 0,1);
   $sAcr = $sAcr.$firstAlphabet ;
}
0

using answer from @codaddict.

i also thought in a case where you have an abbreviated word as the word to be abbreviated e.g DPR and not Development Petroleum Resources, so such word will be on D as the abbreviated version which doesn't make much sense.

function AbbrWords($str,$amt){
        $pst = substr($str,0,$amt);
        $length = strlen($str);
        if($length > $amt){
            return $pst;
        }else{
            return $pst;
        }
    }
    
    function AbbrSent($str,$amt){
        if(preg_match_all('/\b(\w)/',strtoupper($str),$m)) {
            $v = implode('',$m[1]); // $v is now SOQTU
            if(strlen($v) < 2){
                if(strlen($str) < 5){
                    return $str;
                }else{
                    return AbbrWords($str,$amt);
                }
            }else{
                return AbbrWords($v,$amt);
            }
        }
    }
Anthony phillips
  • 152
  • 3
  • 13
0

As an alternative to @user187291's preg_replace() pattern, here is the same functionality without needing a reference in the replacement string.

It works by matching the first occurring word characters, then forgetting it with \K, then it will match zero or more word characters, then it will match zero or more non-word characters. This will consume all of the unwanted characters and only leave the first occurring word characters. This is ideal because there is no need to implode an array of matches. The u modifier ensures that accented/multibyte characters are treated as whole characters by the regex engine.

Code: (Demo)

$tests = [
    'Stack-Overflow Questions Tags Users',
    'Stack Overflow Close Vote Reviewers',
    'Jean-Claude Vandàmme'
];
var_export(
    preg_replace('/\w\K\w*\W*/u', '', $tests)
);

Output:

array (
  0 => 'SOQTU',
  1 => 'SOCVR',
  2 => 'JCV',
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136