Як отримати першу літеру кожного слова для даного рядка?
$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')) є абсолютно необхідним, якщо ви працюєте з багатобайтовими рядками. Використання простого $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є неправильним (він отримує роботу), але є більш елегантний скаже вирішення проблеми. І я не використовую слово «елегантний» естетично, я використовую його технічним способом.
Відповідь Майкла Берковського (та інших), спрощена до одного рядка і правильно працює над багатобайтовими символами (тобто робить абревіатуру / ініціали з нелатинських рядків):
foreach(explode(' ', $words) as $word) $acronym .= mb_substr($word, 0, 1, 'utf-8');
Використовувати mb_substr($word, 0, 1, 'utf-8')замість, $word[0]здається, обов’язково, якщо ви працюєте над нелатинськими багатобайтними рядками та символами, тобто при використанні кодованих рядків UTF-8.
Подобається це
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));
},
''
);
}
NB: це поверне порожній рядок у випадку, якщо даний рядок порожній.
getInitials('Community College District')
рядок 'CCD' (довжина = 3)
getInitials()
рядок '' (довжина = 0)
getInitials('Lorem ipsum dolor sic amet')
рядок 'Lidsa' (довжина = 5)
Звичайно, ви можете додати фільтри до функції зворотного виклику array_reduce(), наприклад, strtoupper()якщо ви віддаєте перевагу лише великі ініціали, наприклад.
$str = 'I am a String!';
echo implode('', array_map(function($v) { return $v[0]; }, explode(' ', $str)));
// would output IaaS
Щось, що я приготував.
/**
* 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 ?
зменшити цей масив до першої літери
$ акронім = array_reduce (str_word_count ("Community College District", 1), функція ($ 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'
Якщо у вхідному рядку більше двох пробілів між двома літерами, спробуйте це.
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);
Ось функція, яка отримує ініціали імені, і якщо ініціали складають лише 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);
}
Спробуйте це-
$strs=explode(" ",$string);
foreach($strs as $str)
echo $str[0];
У випадку, коли ви будете робити це на великих рядках (або навіть безпосередньо з файлу), explode()це не найкращий спосіб це зробити. Уявіть, скільки пам’яті буде витрачено даремно, якщо вам доведеться розділити на пам’ять рядок розміром 2 МБ.
Трохи більше кодування і (припускаючи 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);
}
?>
по-перше, я вибухаю рядок пробілами, потім спочатку підряджую char.
Спробуйте це
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 Expression над будь-яким іншим способом вилучення рядків, але якщо ви не знайомі з Reg Ex, тоді hear - це метод, що використовує функцію explode()PHP:
$string = "David Beckham";
$string_split = explode(" ", $string);
$inititals = $string_split[0][0] . $string_split[1][0];
echo $inititals;
Очевидно, що наведений вище код працюватиме лише для імені, що містить два слова.
Ця відповідь 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;
}
}
Ви можете використовувати цю функцію на основі прийнятої відповіді від @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);