得到每个单词的第一个字母


81

如何获得给定字符串的每个单词的首字母?

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

我找到了javascript方法,但不确定如何将其转换为php。


1
您是否想知道如何根据问题的短语表达方式获取字符串的首字母,或者根据示例获取如何获取每个单词的首字母?如果是前者:$ result = $ string [0]。
2012年

您确定每个单词都用一个空格隔开吗?What__about__this__sentence?What about.This sentence?
Mike B

坦率地说,用PHP开发自己的脚本。
2012年

哪些字符可以用作分隔符?空格,破折号,下划线等?
超现实主义梦想

1
在空白处爆炸字符串,然后循环遍历结果数组,由于每个字符串都是一个字符串,因此您可以使用$ string [0]获取第一个字符,然后简单地将它们串联起来。
slash197

Answers:


136

explode()在空格上,然后使用[]表示法以数组形式访问结果字符串:

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

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

如果您期望多个空格可以分隔单词,请改用 preg_split()

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

或者-,_,例如,如果非空格字符分隔单词(),请同时使用preg_split()

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

14
要点:preg_match_all("/[A-Z]/", ucwords(strtolower($string)), $matches);
dmmd

46

最好的方法是使用正则表达式。

让我们以合乎逻辑的方式分解您想要的东西:您希望字符串中的每个字符都在单词的开头。识别这些字符的最佳方法是查找以空格开头的那些字符。

所以我们先从回顾后为空格字符,后跟任何字符:

/(?<=\s)./

这将找到任何以空格开头的字符。但是-字符串中的第一个字符是您要提取的字符串中的一个字符。并且因为它是字符串中的第一个字符,所以不能在其后加上空格。因此,我们想匹配任何以空格字符串中第一个字符开头的内容,因此我们添加了一个主题开始断言

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

现在我们越来越近了。但是,如果字符串包含多个空格块怎么办?如果包含空格和标点符号,该怎么办?我们可能不想匹配其中任何一个,粗略地说,我们可能只想匹配字母。我们可以使用角色类 来做到这一点[a-zA-Z]。我们可以使用i 修饰符使表达式不区分大小写。

因此,我们最终得到:

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

但是我们如何在PHP中实际使用它呢?好吧,我们想匹配字符串中所有出现的正则表达式,所以我们使用(您猜对了)preg_match_all()

$string = "Progress in Veterinary Science";

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

现在,我们有了要提取的所有字符。要构造您显示的结果字符串,我们需要将它们再次结合在一起

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

...并且我们需要确保它们都是大写的

$result = strtoupper($result);

这就是全部。

看到它正常工作


1
如果您希望也可以使用(?<=\b)代替(?<=\s|^),这将允许您捕获由连字符,句号等分隔的单词的初始字母(基本上是“非单词”字符,与\ w或\ W不匹配的字符),但也可能最终捕获了您不想要的东西。
Leigh

您的解决方案很有帮助!谢谢 !
yathrakaaran

1
绝对应该是答案。非常详细,效果完美,谢谢!
史蒂夫·鲍曼

这对我有所帮助,但是$ string =“兽医科学进展(布鲁克县)”的情况如何?'B'被删除。任何想法
Ken

17

假设所有单词都用空格分开,这是一个合适的解决方案:

$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"

我认为$ word [0]比substr($ word,0,1)快,所以为什么要使用substr($ word,0,1)?
l33tname先生13年

1
我只是不太相信字符串作为数组。过去我弹出过一些错误
casraf

编辑:TL; DR:只是旧习惯
卡斯拉夫

2
@LeonardChallis我不知道,如果Chen Asraf遇到这种错误,但是如果要对多字节字符串进行操作,则绝对必须使用substr($word,0,1)(或实际上是- mb_substr($word, 0, 1, 'utf-8'))。使用简单$word[0]会砍掉多字节字符的一半,并给您不正确的首字母-一些奇怪的符号而不是实际的字母。如果您将此情况视为错误,那么您就可以找到答案!:]
trejder 2014年

任何方法或方法都可以忽略诸如(in,the,of,...)之类的单词,并将其输出为“ PVS”而不是“
PIVS

9

有很多explode答案。我认为使用该strtok函数是一种更优雅,内存效率更高的解决方案:

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);

这是更健壮和有用的功能,它支持UTF8字符以及仅使用大写单词的选项:

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);

我不同意,与爆炸方法相比,您的代码量很大。
Dale

3
@Dale好吧,这比我们的代码更能告诉您关于您的信息-美观是评估代码的一种糟糕方法。使用explode来解决这个问题是什么将被称为一个天真的解决方案。就像使用冒泡排序算法一样,只是因为它易于实现。
Sverri M. Olsen

@MAssiveAmountsOfCode我不同意为什么要在13行代码中执行某些操作,而这可以在1行中完成foreach(explode(' ', $string) as $word) echo $word[0];?一目了然,不浪费时间。
Dale

在用空格分隔空格的单词字符串上,天真是什么呢?我想你的话告诉我们,你是一个笨拙的编码员,不接受代码审查。
Dale

3
@戴尔我不是要侮辱您,也不是要表现得自负。这是幼稚的,因为爆炸字符串会创建一个不需要使用数组的数组。对字符串进行标记更优雅,因为您正在逐步遍历原始字符串,这需要较少的内存。我并不是说使用explode错误的(可以完成工作),但是解决问题的说法更为优雅。我不是以美学的方式使用“优雅”一词,而是以技术性的方式使用它。
Sverri M. Olsen 2013年

7

Michael Berkowski(和其他人)的答案,简化为一行,并且可以正确处理多字节字符(即,使用非拉丁字符串生成缩写/缩写):

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

如果您正在处理非拉丁,多字节字符串和字符,即使用UTF-8编码的字符串时mb_substr($word, 0, 1, 'utf-8')$word[0]似乎必须使用,而不是。


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

5

像这样

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

真好 我的代码中的第一个字母有问题。什么字符表示首字母?<=
Narek 2013年

1
为+1 \pL。您可以添加一些解释吗?我更喜欢教一个人钓鱼,而不是只给他一个;-)
DaveRandom

@Narek(?<=)这是正面细节
Winston

@DaveRandom此处关于此字符的数据
Winston

@Winston知道(尽管我在回答中采用了KISS方法),但我对OP的意义更大;-)但还是要感谢:-)
DaveRandom 2013年

4

正如其他人所解释的那样,经典方式包括迭代初始字符串的每个单词,将单词还原为第一个字母,然后将这些第一个字母组合在一起。

这是一个结合了不同步骤的帮助方法。

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

注意:如果给定的字符串为空,它将返回一个空字符串。

getInitials('Community College District')

字符串'CCD'(长度= 3)

getInitials()

字符串''(长度= 0)

getInitials('Lorem ipsum dolor sic amet')

字符串'Lidsa'(长度= 5)

当然,您可以向的回调函数添加过滤器array_reduce(),例如,strtoupper()如果您只喜欢大写的首字母缩写的话。


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

// would output IaaS

3

我已经煮熟了

/**
 * 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;
}

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

1

我认为您必须爆炸并再次加入他们的队伍.....

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

1

使用Prateeks基础,这是一个带有说明的简单示例

//  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'

这是我发布到此网站的第一个解决方案。HTH!
Rob Stocki

1

如果输入字符串中两个字母之间有更多的空格,请尝试此操作。

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);

演示1

相同代码的替代

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);

演示2


1

这是一个为您提供名字缩写的函数,如果缩写只有1个字母,则它将返回名字的前2个字母。

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);
}

1

为什么不为此使用str_word_count函数呢?

  1. 将每个单词作为数组中的一行
  2. 数组减少为第一个字母

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



0

这样的事情应该可以解决问题:

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

0

对于要在大字符串上(甚至直接从文件中)执行此操作的情况,explode()不是最佳方法。想象一下,如果必须将2MB大的字符串拆分为内存,将会浪费多少内存。

通过更多的编码和(假设PHP >= 5.0),您可以轻松实现Iterator将完全做到这一点的PHP类。这将接近python中的生成器,长话短说,这是代码:

/**
 * 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);
    }
}

如果要在更具挑战性的字符串上使用它:

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

您能得到预期的结果:

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

因此,您可以轻松地使用它$i[0]来获取第一个字母。您可能会看到,这比将整个字符串拆分到内存(总是只使用尽可能少的内存)更有效。您还可以轻松修改此解决方案,以连续读取文件等。



0

试试这个

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');

0

我喜欢Reg Expression而不是其他任何字符串提取方法,但是如果您不熟悉Reg Ex,那么您会听到使用explode()PHP函数的方法:

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

显然,以上代码仅适用于包含两个单词的名称。


0

这个答案https://stackoverflow.com/a/33080232/1046909但具有多字节字符串支持:

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;
    }
}

0

您可以根据@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;
}

$ length参数确定要显示的字符数

用法:

$acronym = buildAcronym("Hello World", 2);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.