Holen Sie sich den ersten Buchstaben jedes Wortes

81

Wie würde ich den ersten Buchstaben jedes Wortes für eine bestimmte Zeichenfolge erhalten?

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

Ich fand die Javascript-Methode, war mir aber nicht sicher, wie ich sie in PHP konvertieren sollte.

Grigor
quelle
1
Möchten Sie wissen, wie Sie den ersten Buchstaben Ihrer Zeichenfolge erhalten, wie Ihre Frage formuliert ist, oder wie Sie den ersten Buchstaben jedes Wortes erhalten, wie in Ihrem Beispiel? Wenn erstere: $ result = $ string [0].
Anonym
Sie sind sich sicher, dass jedes Wort durch ein Leerzeichen getrennt ist? What__about__this__sentence?oderWhat about.This sentence?
Mike B
Ehrlich gesagt entwickeln Sie Ihr eigenes Skript in PHP.
Lion
Welche Zeichen würden als Trennzeichen gelten? Leerzeichen, Bindestrich, Unterstrich usw.?
Surreale Träume
1
Explodieren Sie die Zeichenfolge in Leerzeichen und durchlaufen Sie dann das Ergebnisarray. Da jede Zeichenfolge eine Zeichenfolge ist, können Sie mit $ string [0] das erste Zeichen abrufen und diese dann einfach verketten.
Slash197

Antworten:

136

explode()In den Leerzeichen verwenden Sie dann die []Notation, um auf die resultierenden Zeichenfolgen als Arrays zuzugreifen:

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

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

Wenn Sie die Erwartung haben, dass mehrere Leerzeichen Wörter trennen können, wechseln Sie stattdessen zu preg_split()

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

Oder wenn andere Zeichen als Leerzeichen beispielsweise Wörter ( -,_) begrenzen , verwenden Sie preg_split()auch:

// Delimit by multiple spaces, hyphen, underscore, comma
$words = preg_split("/[\s,_-]+/", "Community College District");
Michael Berkowski
quelle
14
Auf den Punkt gebracht:preg_match_all("/[A-Z]/", ucwords(strtolower($string)), $matches);
dmmd
46

Dies erreichen Sie am besten mit regulären Ausdrücken.

Lassen Sie uns das, was Sie wollen, auf logische Weise aufschlüsseln: Sie möchten, dass jedes Zeichen aus der Zeichenfolge am Anfang eines Wortes steht. Der beste Weg, um diese Zeichen zu identifizieren, besteht darin, nach Zeichen zu suchen, denen Leerzeichen vorangestellt sind.

Wir beginnen also mit einem Lookbehind für dieses Leerzeichen, gefolgt von einem beliebigen Zeichen:

/(?<=\s)./

Dadurch wird jedes Zeichen gefunden, dem ein Leerzeichen vorangestellt ist. Aber - das erste Zeichen in der Zeichenfolge ist ein Zeichen in der Zeichenfolge, das Sie extrahieren möchten. Und weil es das erste Zeichen in der Zeichenfolge ist, kann kein Leerzeichen vorangestellt werden. Wir möchten also mit allem übereinstimmen, dem ein Leerzeichen oder das erste Zeichen in der Zeichenfolge vorangestellt ist , und fügen daher eine Aussage zum Beginn des Betreffs hinzu :

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

Jetzt kommen wir näher. Was aber, wenn die Zeichenfolge Blöcke mit mehreren Leerzeichen enthält? Was ist, wenn es ein Leerzeichen gefolgt von einem Interpunktionszeichen enthält? Wir wollen wahrscheinlich keine von denen zusammenbringen, in Fett wollen wir wahrscheinlich nur Buchstaben zusammenbringen. Wir können das mit einer Charakterklasse machen [a-zA-Z] . Und wir können mithilfe des i Modifikators festlegen, dass der Ausdruck nicht zwischen Groß- und Kleinschreibung besteht .

Am Ende haben wir also:

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

Aber wie verwenden wir das eigentlich in PHP? Nun, wir möchten alle Vorkommen des regulären Ausdrucks innerhalb der Zeichenfolge abgleichen, also verwenden wir (Sie haben es erraten) preg_match_all():

$string = "Progress in Veterinary Science";

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

Jetzt haben wir alle Zeichen, die wir extrahieren wollten. Um die angezeigte Ergebniszeichenfolge zu erstellen, müssen wir sie erneut zusammenfügen :

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

... und wir müssen sicherstellen, dass sie alle in Großbuchstaben geschrieben sind :

$result = strtoupper($result);

Und das ist wirklich alles.

Sehen Sie, wie es funktioniert

DaveRandom
quelle
1
Wenn Sie möchten, können Sie auch (?<=\b)anstelle von verwenden (?<=\s|^), können Sie die Anfangsbuchstaben von Wörtern erfassen, die durch Bindestriche, Punkte usw. getrennt sind (im Grunde "Nicht-Wort" -Zeichen, die nicht mit \ w oder \ W übereinstimmen). könnte aber auch Dinge erfassen, die Sie nicht wollen.
Leigh
Ihre Lösung hat sehr geholfen! Danke !
Yathrakaaran
1
Dies sollte definitiv die Antwort sein. Sehr detailliert und funktioniert perfekt, danke!
Steve Bauman
Das hat mir geholfen, aber was ist mit dem Fall von $ string = "Fortschritt in der Veterinärwissenschaft (Brower County)"; Das 'B' wird fallen gelassen. Irgendwelche Gedanken
Ken
17

Angenommen, die Wörter sind alle durch Leerzeichen getrennt, ist dies eine geeignete Lösung:

$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"
casraf
quelle
Ich denke, $ word [0] ist schneller als substr ($ word, 0,1). Warum verwenden Sie substr ($ word, 0,1)?
Sir l33tname
1
Ich vertraue Strings als Arrays einfach nicht sehr. Ich habe einige Fehler in der Vergangenheit
aufgetaucht
Edit: TL; DR: nur alte Gewohnheiten
Casraf
2
@LeonardChallis Ich weiß nicht, ob Chen Asraf auf diese Art von Fehlern hingewiesen hat, aber die Verwendung substr($word,0,1)(oder tatsächlich - mb_substr($word, 0, 1, 'utf-8')) ist ein absolutes Muss, wenn Sie mit Mehrbyte -Zeichenfolgen arbeiten. Wenn Sie simple verwenden, $word[0]wird die Mehrbyte-Zeichenhälfte zerhackt und Sie erhalten eine falsche Initiale - ein seltsames Symbol anstelle des tatsächlichen Buchstabens. Wenn Sie diese Situation als Fehler bezeichnen, haben Sie dort Ihre Antwort! :]
Trejder
Jede Methode oder Möglichkeit, Wörter wie (in, the, of, a ...) zu ignorieren und als "PVS" anstelle von "PIVS"
ausgegeben zu werden
9

Es gibt viele explodeAntworten. Ich denke, die Verwendung der strtokFunktion ist eine viel elegantere und speichereffizientere Lösung:

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

Hier ist eine robustere und nützlichere Funktion, die UTF8-Zeichen unterstützt und die Option bietet, nur die großgeschriebenen Wörter zu verwenden:

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);
Sverri M. Olsen
quelle
Ich bin anderer Meinung, Ihr Code ist im Vergleich zu den Explosionsmethoden massiv.
Dale
3
@Dale Nun, das sagt uns mehr über Sie als über meinen Code - Ästhetik ist eine schlechte Methode, um Code zu bewerten. Die explodeLösung dieses Problems wird als naive Lösung bezeichnet . Es ist wie mit dem Blasensortieralgorithmus, nur weil er einfach zu implementieren ist.
Sverri M. Olsen
@MAssiveAmountsOfCode Ich bin nicht einverstanden, warum etwas in 13 Codezeilen gemacht wird, das in 1 erreicht werden kann foreach(explode(' ', $string) as $word) echo $word[0];? Auf einen Blick leichter zu verstehen und keine Zeitverschwendung.
Dale
Was ist auch naiv daran, eine Folge von Wörtern zu teilen, die durch ein Leerzeichen, durch ein Leerzeichen getrennt sind? Ich denke, Ihre Bemerkung sagt uns, dass Sie ein pompöser Codierer sind, der nicht für Codeüberprüfungen offen ist.
Dale
3
@ Dale Ich wollte dich nicht beleidigen oder pompös erscheinen. Es ist naiv, weil das Explodieren eines Strings ein Array erzeugt, in dem eines nicht benötigt wird. Das Tokenisieren der Zeichenfolge ist eleganter, da Sie die ursprüngliche Zeichenfolge durchlaufen, was weniger Speicherplatz erfordert. Ich sage nicht , dass die Verwendung explodeist falsch (es bekommt den Job getan), sondern dass es eine elegantere sagen, das Problem zu lösen. Und ich benutze das Wort "elegant" nicht auf ästhetische Weise, sondern auf technische Weise.
Sverri M. Olsen
7

Michael Berkowskis (und andere) Antwort, vereinfacht auf eine Zeile und korrektes Arbeiten mit Mehrbyte-Zeichen (dh Abkürzung / Initialen aus nicht-lateinischen Zeichenfolgen):

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

Mit mb_substr($word, 0, 1, 'utf-8')statt $word[0]scheint Muss zu sein, wenn man auf nicht-lateinische arbeiten, Multi-Byte - Zeichenketten und Zeichen, das heißt , wenn UTF-8 kodierten Strings verwenden.

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

So was

preg_match_all('#(?<=\s|\b)\pL#u', $String, $Result);
echo '<pre>' . print_r($Result, 1) . '</pre>';
Winston
quelle
Nett. Ich habe ein Problem mit dem ersten Buchstaben in meinem Code. Welches Zeichen zeigt den ersten Buchstaben an? <=?
Narek
1
+1 für \pL. Könnten Sie eine kleine Erklärung hinzufügen? Ich ziehe es vor, einem Mann das Fischen beizubringen, anstatt ihm nur einen zu geben ;-)
DaveRandom
@ Narek (? <=) Dies ist positiv Lookbehind dieses Detail
Winston
@ DaveRandom hier Datum über diese Zeichen
Winston
@ Winston Ich weiß (obwohl ich in meiner Antwort den KISS-Ansatz gewählt habe), ich meinte mehr für das OP ;-) aber trotzdem danke :-)
DaveRandom
4

Wie von anderen erklärt, besteht die klassische Methode darin, jedes Wort Ihrer Anfangszeichenfolge zu durchlaufen, das Wort auf den ersten Buchstaben zu reduzieren und diese ersten Buchstaben miteinander zu kombinieren.

Hier ist eine Hilfsmethode, die die verschiedenen Schritte kombiniert.

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

NB: Dies gibt eine leere Zeichenfolge zurück, falls die angegebene Zeichenfolge leer ist.

getInitials('Community College District')

Zeichenfolge 'CCD' (Länge = 3)

getInitials()

Zeichenfolge '' (Länge = 0)

getInitials('Lorem ipsum dolor sic amet')

Zeichenfolge 'Lidsa' (Länge = 5)

Natürlich können Sie der Rückruffunktion von Filter hinzufügen array_reduce(), z. B. strtoupper()wenn Sie beispielsweise nur Initialen in Großbuchstaben bevorzugen.

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

// would output IaaS
Billyonecan
quelle
3

Etwas, das ich mir ausgedacht habe.

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

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

Ich denke, du musst explodieren und dich ihnen wieder anschließen .....

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

Hier ist ein einfaches Beispiel mit Erklärungen zur Verwendung der Prateeks Foundation

//  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'
Rob Stocki
quelle
Dies ist meine erste Lösung, die auf dieser Website veröffentlicht wurde. HTH!
Rob Stocki
1

Wenn die Eingabezeichenfolge mehr Leerzeichen zwischen zwei Buchstaben enthält, versuchen Sie dies.

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

Alternative zum gleichen Code

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

Durgesh Tiwari
quelle
1

Hier ist eine Funktion, mit der Sie die Initialen eines Namens erhalten. Wenn die Initialen nur aus 1 Buchstaben bestehen, werden die ersten 2 Buchstaben des Vornamens zurückgegeben.

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);
}
Salam
quelle
1

Warum nicht die Funktion str_word_count verwenden?

  1. Holen Sie sich jedes Wort als Zeile in einem Array
  2. Reduzieren Sie dieses Array auf den ersten Buchstaben

    $ acronym = array_reduce (str_word_count ("Community College District", 1), Funktion ($ res, $ w) {return $ res. $ w [0];});

Spir
quelle
0

Versuche dies-

$strs=explode(" ",$string);

foreach($strs as $str)
  echo $str[0];
Prateek Shukla
quelle
0

So etwas sollte den Trick machen:

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

Für den Fall, dass Sie dies mit großen Zeichenfolgen (oder sogar direkt aus einer Datei) explode()tun, ist dies nicht der beste Weg, dies zu tun. Stellen Sie sich vor, wie viel Speicher verschwendet wird, wenn Sie eine 2 MB große Zeichenfolge in den Speicher aufteilen müssen.

Mit etwas mehr Codierung und (vorausgesetzt PHP >= 5.0) können Sie einfach die PHP- IteratorKlasse implementieren , die genau dies tut. Dies wird in der Nähe des Generators in Python sein und kurz gesagt, hier ist der Code:

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

Und wenn Sie es für eine etwas anspruchsvollere Saite verwenden:

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

Erhalten Sie das erwartete Ergebnis:

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

Sie können also problemlos $i[0]den ersten Buchstaben abrufen. Sie können wahrscheinlich feststellen, dass dies eine effektivere Lösung ist, als die gesamte Zeichenfolge in den Speicher aufzuteilen (verwenden Sie immer nur so wenig Speicher wie möglich). Sie können diese Lösung auch leicht ändern, um das kontinuierliche Lesen von Dateien usw. zu ermöglichen.

Vyktor
quelle
0
<?php $arr = explode(" ",$String);

foreach($arr as $s)
{
   echo substr($s,0,1);
}

?>

Zuerst explodiere ich einen String durch Leerzeichen, dann erst ein Zeichen.

http://php.net/substr

http://php.net/explode

Robert
quelle
0

Versuche dies

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');
San
quelle
0

Ich mag Reg Expression gegenüber jeder anderen Methode der Zeichenfolgenextraktion, aber wenn Sie mit Reg Ex nicht vertraut sind, ist Hear eine Methode, die die explode()PHP-Funktion verwendet:

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

Offensichtlich funktioniert der obige Code nur für einen Namen, der zwei Wörter enthält.

Matt Jameson
quelle
0

Diese Antwort https://stackoverflow.com/a/33080232/1046909, jedoch mit Unterstützung für Multibyte-Zeichenfolgen:

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;
    }
}
MingalevME
quelle
0

Sie können diese Funktion basierend auf der akzeptierten Antwort von @Michael Berkowski verwenden

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

Der Parameter $ length bestimmt, wie viele Zeichen Sie anzeigen möchten

VERWENDUNG:

$acronym = buildAcronym("Hello World", 2);
Couranos
quelle