lấy chữ cái đầu tiên của mỗi từ


81

Làm cách nào để lấy ký tự đầu tiên của mỗi từ cho một chuỗi đã cho?

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

Tôi đã tìm thấy phương pháp javascript nhưng không chắc chắn cách chuyển đổi nó sang php.


1
Bạn có muốn biết cách lấy chữ cái đầu tiên của chuỗi, theo cách diễn đạt câu hỏi của bạn hoặc cách lấy chữ cái đầu tiên của mỗi từ, theo ví dụ của bạn? Nếu trước đây: $ result = $ string [0].
Ẩn danh

Bạn khẳng định rằng mỗi từ được phân tách bằng một dấu cách? What__about__this__sentence?hoặcWhat about.This sentence?
Mike B

Thẳng thắn phát triển tập lệnh của riêng bạn bằng PHP.
Lion

Những ký tự nào sẽ đủ điều kiện làm dấu phân cách? Dấu cách, dấu gạch ngang, dấu gạch dưới, v.v.?
Những giấc mơ siêu thực vào

1
bùng nổ chuỗi tại các khoảng trắng sau đó lặp qua mảng kết quả và vì mỗi chuỗi là một chuỗi nên bạn có thể sử dụng $ string [0] để lấy ký tự đầu tiên sau đó chỉ cần nối các ký tự đó.
Slash197,

Câu trả lời:


136

explode()trên khoảng trắng, sau đó bạn sử dụng []ký hiệu để truy cập các chuỗi kết quả dưới dạng mảng:

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

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

Nếu bạn mong đợi rằng nhiều khoảng trắng có thể phân tách các từ, hãy chuyển sang preg_split()

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

Hoặc nếu các ký tự khác với các từ phân cách bằng khoảng trắng ( -,_) chẳng hạn, hãy sử dụng preg_split():

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

14
Về vấn đề:preg_match_all("/[A-Z]/", ucwords(strtolower($string)), $matches);
dmmd

46

Cách tốt nhất để thực hiện điều này là với các biểu thức chính quy.

Hãy chia nhỏ những gì bạn muốn theo cách hợp lý: Bạn muốn mọi ký tự từ chuỗi đều ở đầu một từ. Cách tốt nhất để xác định những ký tự đó là tìm kiếm những ký tự đứng trước khoảng trắng.

Vì vậy, chúng tôi bắt đầu với một cái nhìn sau cho ký tự khoảng trắng đó, tiếp theo là bất kỳ ký tự nào:

/(?<=\s)./

Điều này sẽ tìm thấy bất kỳ ký tự nào đứng trước một khoảng trắng. Nhưng - ký tự đầu tiên trong chuỗi là ký tự trong chuỗi là ký tự bạn muốn trích xuất. Và bởi vì nó là ký tự đầu tiên trong chuỗi, nó không thể được đặt trước bởi một khoảng trắng. Vì vậy, chúng tôi muốn so khớp bất kỳ thứ gì đứng trước khoảng trắng hoặc ký tự đầu tiên trong chuỗi, vì vậy chúng tôi thêm một xác nhận bắt đầu của chủ đề :

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

Bây giờ chúng tôi đang tiến gần hơn. Nhưng điều gì sẽ xảy ra nếu chuỗi chứa các khối nhiều khoảng trắng? Điều gì sẽ xảy ra nếu nó chứa một khoảng trắng theo sau là một ký tự dấu câu? Chúng tôi có thể không muốn ghép bất kỳ cái nào trong số đó, về chất béo, chúng tôi có thể chỉ muốn ghép các chữ cái. Chúng ta có thể làm điều đó với một lớp nhân vật [a-zA-Z] . Và chúng ta có thể thực hiện biểu thức không phân biệt chữ hoa chữ thường bằng cách sử dụng công cụ i sửa đổi .

Vì vậy, chúng tôi kết thúc với:

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

Nhưng làm thế nào để chúng ta thực sự sử dụng điều này trong PHP? Chúng tôi muốn đối sánh tất cả các lần xuất hiện của biểu thức chính quy trong chuỗi nên chúng tôi sử dụng (bạn đoán vậy) preg_match_all():

$string = "Progress in Veterinary Science";

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

Bây giờ chúng tôi có tất cả các ký tự mà chúng tôi muốn trích xuất. Để xây dựng chuỗi kết quả mà bạn hiển thị, chúng ta cần nối chúng lại với nhau :

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

... và chúng ta cần đảm bảo rằng chúng đều là chữ hoa :

$result = strtoupper($result);

Và đó thực sự là tất cả những gì cần làm.

Thấy nó hoạt động


1
Nếu bạn muốn, bạn cũng có thể sử dụng (?<=\b)thay thế (?<=\s|^), điều này sẽ cho phép bạn nắm bắt các chữ cái đầu tiên của các từ được phân tách bằng dấu gạch ngang, dấu dừng đầy đủ, v.v. (về cơ bản là các ký tự "không phải từ", những ký tự sẽ không khớp với \ w hoặc \ W), nhưng cũng có thể kết thúc việc chụp những thứ bạn không muốn.
Leigh

Giải pháp của bạn đã giúp rất nhiều! Cảm ơn bạn !
yathrakaaran

1
Đây chắc chắn phải là câu trả lời. Cực kỳ chi tiết và hoạt động hoàn hảo, cảm ơn!
Steve Bauman

Điều này đã giúp tôi, nhưng còn trường hợp của $ string = "Tiến bộ trong Khoa học Thú y (Brower County)"; chữ 'B' bị bỏ. Mọi suy nghĩ
Ken

17

Giả sử tất cả các từ được phân chia bằng dấu cách, đây là một giải pháp phù hợp:

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

Tôi nghĩ $ word [0] nhanh hơn substr ($ word, 0,1), vậy tại sao bạn lại sử dụng substr ($ word, 0,1)?
Sir l33tname

1
Tôi chỉ không tin tưởng lắm về chuỗi dưới dạng mảng. Tôi đã có một số lỗi bật lên trong quá khứ
casraf

Chỉnh sửa: TL; DR: chỉ là thói quen cũ
casraf

2
@LeonardChallis Tôi không biết, liệu Chen Asraf có mắc phải lỗi này không, nhưng việc sử dụng substr($word,0,1)(hoặc thực sự - mb_substr($word, 0, 1, 'utf-8')) là điều tuyệt đối bắt buộc, nếu bạn đang hoạt động trên chuỗi nhiều byte. Sử dụng đơn giản $word[0]sẽ cắt một nửa ký tự nhiều byte và cung cấp cho bạn ký tự đầu tiên không chính xác - một số ký hiệu lạ thay vì ký tự thực tế. Nếu bạn coi tình huống này là một lỗi, thì bạn đã có câu trả lời cho mình! :]
trejder

Bất kỳ phương pháp hoặc cách nào để bỏ qua các từ như (in, the, of, a ...) và nhận đầu ra là "PVS" thay vì "PIVS"
Fenil Shah

9

Có rất nhiều explodecâu trả lời. Tôi nghĩ rằng sử dụng strtokhàm là một giải pháp thanh lịch và tiết kiệm bộ nhớ hơn nhiều:

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

Đây là một chức năng hữu ích và mạnh mẽ hơn, hỗ trợ các ký tự UTF8 và tùy chọn chỉ sử dụng các từ viết hoa:

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

Tôi không đồng ý, mã của bạn quá lớn so với các phương pháp bùng nổ.
Dale

3
@Dale Chà, điều đó cho chúng tôi biết nhiều điều về bạn hơn là về mã của tôi - tính thẩm mỹ là một cách đánh giá mã kém. Sử dụng explodeđể giải quyết vấn đề này là những gì sẽ được gọi là một giải pháp ngây thơ . Nó giống như sử dụng thuật toán sắp xếp bong bóng chỉ vì nó dễ thực hiện.
Sverri M. Olsen

@MAssiveAmountsOfCode Tôi không đồng ý tại sao thực hiện điều gì đó trong 13 dòng mã, mà có thể đạt được trong 1 foreach(explode(' ', $string) as $word) echo $word[0];? Dễ hiểu hơn trong nháy mắt và không lãng phí thời gian.
Dale

Ngoài ra, điều gì là ngây thơ về việc tách một chuỗi từ được phân tách bằng dấu cách, bởi dấu cách? Tôi nghĩ nhận xét của bạn cho chúng tôi biết rằng bạn là một lập trình viên hào hoa, không cởi mở với các bài đánh giá về mã.
Dale

3
@Dale Tôi không có ý xúc phạm bạn hay tỏ ra hào hoa. Thật là ngây thơ vì việc phát nổ một chuỗi sẽ tạo ra một mảng, trong đó một mảng không cần thiết. Mã hóa chuỗi thanh lịch hơn vì bạn đang bước qua chuỗi ban đầu, đòi hỏi ít bộ nhớ hơn. Tôi không nói rằng việc sử dụng explodesai (nó hoàn thành công việc), nhưng có một cách nói thanh lịch hơn về việc giải quyết vấn đề. Và tôi không sử dụng từ "thanh lịch" theo cách thẩm mỹ, tôi đang sử dụng nó theo cách chuyên môn.
Sverri M. Olsen

7

Câu trả lời của Michael Berkowski (và những người khác), được đơn giản hóa thành một dòng và hoạt động chính xác trên các ký tự nhiều byte (tức là tạo chữ viết tắt / viết tắt từ chuỗi không phải Latinh):

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

Việc sử dụng mb_substr($word, 0, 1, 'utf-8'), thay vì $word[0]dường như là phải, nếu bạn đang làm việc trên các chuỗi và ký tự không phải Latinh, nhiều byte, tức là khi sử dụng các chuỗi được mã hóa UTF-8.


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

5

Như thế này

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

Đẹp. Tôi gặp vấn đề với chữ cái đầu tiên trong mã của mình. Ký tự nào chỉ chữ cái đầu tiên? <=?
Narek

1
+1 cho \pL. Bạn có thể thêm một lời giải thích mặc dù? Tôi thích dạy anh ta cách cá chứ không phải chỉ cho anh ta một ;-)
DaveRandom

@Narek (? <=) Đây là Cái nhìn tích cực sau chi tiết này
Winston

@DaveRandom đây dữ liệu về ký tự này
Winston

@Winston tôi biết (mặc dù tôi đã tiếp cận KISS trong câu trả lời của tôi), tôi có nghĩa hơn đối với OP ;-) nhưng nhờ anyway :-)
DaveRandom

4

Như những người khác đã giải thích, cách cổ điển bao gồm việc lặp lại từng từ trong chuỗi ban đầu của bạn, giảm từ đó thành chữ cái đầu tiên của nó và kết hợp các chữ cái đầu tiên đó lại với nhau.

Đây là một phương pháp trợ giúp kết hợp các bước khác nhau.

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

NB: điều này sẽ trả về một chuỗi trống trong trường hợp chuỗi đã cho là trống.

getInitials('Community College District')

chuỗi 'CCD' (chiều dài = 3)

getInitials()

chuỗi '' (length = 0)

getInitials('Lorem ipsum dolor sic amet')

chuỗi 'Lidsa' (chiều dài = 5)

Tất nhiên, bạn có thể thêm bộ lọc vào hàm gọi lại của array_reduce(), chẳng hạn như strtoupper()nếu bạn chỉ thích các chữ cái đầu viết hoa chẳng hạn.


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

// would output IaaS

3

Tôi đã nấu một cái gì đó.

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

Tôi nghĩ bạn phải bùng nổ và tham gia cùng họ trở lại .....

<?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

Sử dụng nền tảng Prateeks, đây là một ví dụ đơn giản kèm theo giải thích

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

Đây là giải pháp đầu tiên của tôi được đăng lên trang web này. HTH!
Rob Stocki

1

Nếu có nhiều khoảng cách hơn giữa hai chữ cái trong chuỗi đầu vào thì hãy thử điều này.

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

Demo1

Thay thế của cùng một mã

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

Đây là một hàm cung cấp cho bạn các chữ cái đầu của tên và nếu các chữ cái đầu chỉ là 1 chữ cái thì nó trả về 2 chữ cái đầu tiên của tên.

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

Tại sao không sử dụng hàm str_word_count cho việc này?

  1. lấy từng từ dưới dạng một hàng trong một mảng
  2. giảm mảng đó xuống chữ cái đầu tiên

    $ acronym = array_reduce (str_word_count ("Khu đại học cộng đồng", 1), function ($ res, $ w) {return $ res. $ w [0];});



0

Một cái gì đó như thế này sẽ thực hiện thủ thuật:

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

0

Đối với trường hợp bạn sẽ thực hiện việc này trên các chuỗi lớn (hoặc thậm chí trực tiếp từ tệp) explode()không phải là cách tốt nhất để làm điều này. Hãy tưởng tượng sẽ lãng phí bao nhiêu bộ nhớ nếu bạn phải chia chuỗi lớn 2MB vào bộ nhớ.

Với ít mã hóa hơn và (giả sử PHP >= 5.0) bạn có thể dễ dàng triển khai Iteratorlớp PHP sẽ thực hiện chính xác điều này. Điều này sẽ gần với trình tạo trong python và câu chuyện ngắn, đây là mã:

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

Và nếu bạn sẽ sử dụng nó trên một chuỗi khó khăn hơn một chút:

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

Bạn sẽ nhận được kết quả mong đợi:

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

Vì vậy, bạn có thể dễ dàng sử dụng $i[0]để tìm nạp ký tự đầu tiên. Bạn có thể thấy rằng đây là giải pháp hiệu quả hơn là chia toàn bộ chuỗi vào bộ nhớ (luôn chỉ sử dụng bộ nhớ ít nhất có thể). Bạn cũng có thể dễ dàng sửa đổi giải pháp này để làm việc với việc đọc tệp liên tục, v.v.



0

Thử đi

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

Tôi thích Reg Expression hơn bất kỳ phương pháp trích xuất chuỗi nào khác, nhưng nếu bạn không quen với Reg Ex thì hãy nghe đây là một phương pháp sử dụng explode()hàm PHP:

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

Rõ ràng đoạn mã trên sẽ chỉ hoạt động trên một tên có chứa hai từ.


0

Câu trả lời này https://stackoverflow.com/a/33080232/1046909 nhưng với hỗ trợ chuỗi multibyte:

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

Bạn có thể sử dụng chức năng đó dựa trên câu trả lời được chấp nhận từ @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;
}

Tham số $ length xác định số lượng ký tự bạn muốn hiển thị

SỬ DỤNG:

$acronym = buildAcronym("Hello World", 2);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.