Create acronym from a string containing only words
Asked Answered
F

11

17

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"

Fulmis answered 9/9, 2010 at 14:56 Comment(2)
How is Stack-Overflow two words? It is not separated by space.Frederik
You have to define "word" first. In terms which PHP can understand. The rest is easy.Anathematize
M
22

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.

Modred answered 9/9, 2010 at 15:0 Comment(4)
Can this be modified to convert small text to capitals?Fulmis
is this related to the current question or a different question?Modred
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.Fulmis
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 againFulmis
D
27
$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',
Deepdyed answered 9/9, 2010 at 16:11 Comment(3)
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"Declarative
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 setsDeclarative
How would you do it so that it ignores the dash - Eg. SQTU is returned?Shaylashaylah
M
22

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.

Modred answered 9/9, 2010 at 15:0 Comment(4)
Can this be modified to convert small text to capitals?Fulmis
is this related to the current question or a different question?Modred
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.Fulmis
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 againFulmis
G
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;
Gestalt answered 9/9, 2010 at 15:36 Comment(3)
interesting that it picks up caps in the same word. that could certainly be useful.Fulmis
That's a "side-effect" of the ucwords() function... makes it useful for capitalising double-barelled namesGestalt
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))));Declarative
V
5
$initialism = preg_replace('/\b(\w)\w*\W*/', '\1', $string);
Vito answered 9/9, 2010 at 15:2 Comment(0)
F
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;
}
Frederik answered 9/9, 2010 at 15:0 Comment(0)
S
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)

Sumptuous answered 9/9, 2010 at 15:2 Comment(0)
S
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];
Shannashannah answered 9/9, 2010 at 15:4 Comment(1)
+1 for being different, and using str_word_count. Pity you can't define '-' as a word separatorGestalt
R
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
Resnick answered 9/9, 2010 at 15:23 Comment(3)
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...Fulmis
And all that without having to spend your otherwise-productive hours dithering with regular expressions.Resnick
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.Resnick
E
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 ;
}
Epigenous answered 24/7, 2020 at 7:25 Comment(0)
H
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);
            }
        }
    }
Heath answered 22/10, 2021 at 12:54 Comment(0)
G
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',
)
Gasperoni answered 7/2, 2023 at 22:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.