文字列内の各単語の最初の文字を取得します


81

特定の文字列の各単語の最初の文字を取得するにはどうすればよいですか?

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

javascriptメソッドを見つけましたが、phpに変換する方法がわかりませんでした。


1
質問の表現方法に従って文字列の最初の文字を取得する方法、または例のように各単語の最初の文字を取得する方法を知りたいですか?前者の場合:$ result = $ string [0]。
匿名

各単語が1つのスペースで区切られていることを確信していますか?What__about__this__sentence?またはWhat about.This sentence?
Mike B

率直に言って、PHPで独自のスクリプトを開発してください。
ライオン

区切り文字として適格となる文字は何ですか?スペース、ダッシュ、アンダースコアなど?
シュールな夢

1
空白で文字列を分解してから、結果の配列をループします。各文字列は文字列であるため、$ string [0]を使用して最初の文字を取得し、それらを単純に連結できます。
slash197 2013

回答:


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 2014年

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に一致しない文字)をキャプチャできます。しかし、あなたが望まないものをキャプチャしてしまう可能性もあります。
リー

あなたの解決策は大いに役立ちました!ありがとうございました !
yathrakaaran 2016

1
これは間違いなく答えになるはずです。非常に詳細で完璧に機能します、ありがとう!
スティーブバウマン2016

これは私を助けましたが、$ string = "Progress in Veterinary Science(Brower County)"の場合はどうでしょうか。「B」は削除されます。任意の考え
ケン

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 2013

1
私は文字列を配列としてあまり信頼していません。過去にいくつかのエラーがポップアップしました
casraf 2013

編集:TL; DR:古い習慣
casraf 2013年

2
場合、私は、知らない@LeonardChallis陳Asrafは、エラーのこの種のrefferingが、使用していたsubstr($word,0,1)(または実際には- mb_substr($word, 0, 1, 'utf-8'))あなたはしているが、マルチバイト文字列で動作している場合、絶対必要です。simple$word[0]を使用すると、マルチバイト文字の半分が切り取られ、誤ったイニシャル(実際の文字ではなく奇妙な記号)が表示されます。この状況をエラーと呼ぶなら、あなたはあなたの答えを持っています!:]
trejder 2014

(in、the、of、a ...)のような単語を無視し、「PIVS」ではなく「PVS」として出力を取得する方法または方法
FenilShah19年

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

私は同意しません、あなたのコードはexplodeメソッドと比較して巨大です。
デール

3
@Daleええと、それは私のコードよりもあなたのことを教えてくれます-美学はコードを評価するための悪い方法です。explodeこの問題を解決するために使用するのは、ナイーブソリューションと呼ばれるものです。これは、実装が簡単であるという理由だけで、バブルソートアルゴリズムを使用するようなものです。
Sverri M. Olsen 2013

@MAssiveAmountsOfCode 1で達成できる、13行のコードで何かを行う理由に同意しませforeach(explode(' ', $string) as $word) echo $word[0];ん。時間の無駄ではなく、一目で理解しやすくなります。
デール

また、スペースで区切られた単語の文字列をスペースで分割することについて、何がナイーブですか?あなたの発言は、あなたがコードレビューを受け入れていない豪華なコーダーであることを示していると思います。
デール

3
@デール私はあなたを侮辱したり、派手に見せたりするつもりはありませんでした。文字列を分解すると配列が作成され、必要のない配列が作成されるため、これは単純です。文字列のトークン化は、必要なメモリが少ない元の文字列をステップ実行するため、より洗練されています。私は使用explode間違っていると言っているのではありません(それは仕事を成し遂げます)が、問題を解決するというよりエレガントな言い方があります。そして、私は「エレガント」という言葉を美的な方法で使用しているのではなく、技術的な方法で使用しています。
Sverri M. Olsen 2013

8

Michael Berkowski(およびその他)の回答。1行に簡略化され、マルチバイト文字で正しく機能します(つまり、非ラテン文字列から略語/イニシャルを作成します)。

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

このような

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

いいね。コードの最初の文字に問題がありました。最初の文字を示す文字は何ですか?<=
ナレク2013

1
+1 \pL。少し説明をお願いします。私は男性に魚を与えるだけでなく、魚を教えることを好みます;-)
DaveRandom 2013

@Narek(?<=)これはこの詳細の
Winston

@DaveRandomここでこの文字についてのデータ
Winston

@Winston私は知っています(私の答えではKISSアプローチを採用しましたが)、私はOPのためにもっと意味がありました;-)しかしとにかく感謝します:-)
DaveRandom 2013

5

他の人が説明しているように、古典的な方法は、最初の文字列の各単語を繰り返し処理し、単語を最初の文字に減らし、それらの最初の文字を組み合わせるというものです。

これは、さまざまなステップを組み合わせたヘルパーメソッドです。

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

2

これにstr_word_count関数を使用しないのはなぜですか?

  1. 各単語を配列の行として取得します
  2. その配列を最初の文字に減らします

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


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 2013年

1

入力文字列の2つの文字の間にスペースが多い場合は、これを試してください。

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

Demo2


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


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 Exに慣れていない場合は、explode()PHP関数を使用する方法を聞いてください。

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

明らかに、上記のコードは2つの単語を含む名前でのみ機能します。


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

@MichaelBerkowskiからの回答に基づいてその関数を使用できます

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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.