特定の文字列の各単語の最初の文字を取得するにはどうすればよいですか?
$string = "Community College District";
$result = "CCD";
javascriptメソッドを見つけましたが、phpに変換する方法がわかりませんでした。
特定の文字列の各単語の最初の文字を取得するにはどうすればよいですか?
$string = "Community College District";
$result = "CCD";
javascriptメソッドを見つけましたが、phpに変換する方法がわかりませんでした。
What__about__this__sentence?
またはWhat about.This sentence?
回答:
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");
preg_match_all("/[A-Z]/", ucwords(strtolower($string)), $matches);
これを実現する最良の方法は、正規表現を使用することです。
論理的な方法で必要なものを分解しましょう。文字列のすべての文字が単語の先頭にあるようにします。これらの文字を識別する最良の方法は、空白が前に付いている文字を探すことです。
したがって、そのスペース文字の後ろ書きから始めて、その後に任意の文字を続けます。
/(?<=\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);
そして、それが本当にすべてです。
(?<=\b)
代わりに使用することもできれば(?<=\s|^)
、ハイフンやピリオドなどで区切られた単語の最初の文字(基本的に「単語以外」の文字、\ wまたは\ Wに一致しない文字)をキャプチャできます。しかし、あなたが望まないものをキャプチャしてしまう可能性もあります。
単語がすべてスペースで分割されていると仮定すると、これは適切な解決策です。
$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"
substr($word,0,1)
(または実際には- mb_substr($word, 0, 1, 'utf-8')
)あなたはしているが、マルチバイト文字列で動作している場合、絶対必要です。simple$word[0]
を使用すると、マルチバイト文字の半分が切り取られ、誤ったイニシャル(実際の文字ではなく奇妙な記号)が表示されます。この状況をエラーと呼ぶなら、あなたはあなたの答えを持っています!:]
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
この問題を解決するために使用するのは、ナイーブソリューションと呼ばれるものです。これは、実装が簡単であるという理由だけで、バブルソートアルゴリズムを使用するようなものです。
foreach(explode(' ', $string) as $word) echo $word[0];
ん。時間の無駄ではなく、一目で理解しやすくなります。
explode
が間違っていると言っているのではありません(それは仕事を成し遂げます)が、問題を解決するというよりエレガントな言い方があります。そして、私は「エレガント」という言葉を美的な方法で使用しているのではなく、技術的な方法で使用しています。
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]
する必要があるようです。
このような
preg_match_all('#(?<=\s|\b)\pL#u', $String, $Result);
echo '<pre>' . print_r($Result, 1) . '</pre>';
<=
?
\pL
。少し説明をお願いします。私は男性に魚を与えるだけでなく、魚を教えることを好みます;-)
他の人が説明しているように、古典的な方法は、最初の文字列の各単語を繰り返し処理し、単語を最初の文字に減らし、それらの最初の文字を組み合わせるというものです。
これは、さまざまなステップを組み合わせたヘルパーメソッドです。
/**
* @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()
大文字のイニシャルのみを使用する場合など、のコールバック関数にフィルターを追加できます。
私が作ったもの。
/**
* 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;
}
これにstr_word_count関数を使用しないのはなぜですか?
その配列を最初の文字に減らします
$ acronym = array_reduce(str_word_count( "Community College District"、1)、function($ res、$ w){return $ res。$ w [0];});
私はあなたが爆発して再び彼らに加わる必要があると思います.....
<?php
$string = "Progress in Veterinary Science";
$pieces = explode(" ", $string);
$str="";
foreach($pieces as $piece)
{
$str.=$piece[0];
}
echo $str; /// it will result into "PiVS"
?>
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'
入力文字列の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);
同じコードの代替
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);
これを試して-
$strs=explode(" ",$string);
foreach($strs as $str)
echo $str[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]
最初の文字をフェッチするために簡単に使用できます。これは、文字列全体をメモリに分割するよりも効果的なソリューションであることがわかります(常にできるだけ少ないメモリのみを使用します)。また、このソリューションを簡単に変更して、ファイルなどの継続的な読み取りを処理することもできます。
<?php $arr = explode(" ",$String);
foreach($arr as $s)
{
echo substr($s,0,1);
}
?>
最初に文字列をスペースで分解し、次に最初の文字をsubstrします。
これを試して
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');
私は他の文字列抽出方法よりも正規表現が好きですが、Reg Exに慣れていない場合は、explode()
PHP関数を使用する方法を聞いてください。
$string = "David Beckham";
$string_split = explode(" ", $string);
$inititals = $string_split[0][0] . $string_split[1][0];
echo $inititals;
明らかに、上記のコードは2つの単語を含む名前でのみ機能します。
この回答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;
}
}
@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);