PHP-Teilstring-Extraktion. Holen Sie sich die Zeichenfolge vor dem ersten '/' oder der gesamten Zeichenfolge


170

Ich versuche einen Teilstring zu extrahieren. Ich brauche Hilfe dabei in PHP.

Hier sind einige Beispielzeichenfolgen, mit denen ich arbeite, und die Ergebnisse, die ich benötige:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

Ich möchte die Zeichenfolge bis zur ersten erhalten /, aber wenn keine /vorhanden ist, holen Sie sich die gesamte Zeichenfolge.

Ich habe es versucht,

substr($mystring, 0, strpos($mystring, '/'))

Ich denke, es heißt - holen Sie sich die Position von /und dann den Teilstring von Position 0 zu dieser Position.

Ich weiß nicht, wie ich mit dem Fall umgehen soll, in dem es keinen gibt /, ohne die Aussage zu groß zu machen.

Gibt es eine Möglichkeit, diesen Fall auch zu behandeln, ohne die PHP-Anweisung zu komplex zu machen?


1
Möglicherweise finden Sie s($str)->beforeFirst('/')hilfreiche Informationen in dieser eigenständigen Bibliothek .
Caw

Antworten:


261

Verwenden explode()

$arr = explode("/", $string, 2);
$first = $arr[0];

In diesem Fall verwende ich den limitParameter, explodedamit PHP den String nicht mehr scannt, als benötigt wird.


2
+1 Danke für die Antwort. Es hat funktioniert :) Aber eine Frage. Ich kann das nur -> $arr = explode('/',$mystring,2); echo $arr[0];. Ich kann den ersten String in einer Anweisung selbst nicht abrufen - echo explode('/',$mystring,2)[0];. Da explode ein Array zurückgibt, sollte ich es richtig machen können? Aber ich bekomme einen Fehler. Irgendwelche Vorschläge?

1
PHP mag es nicht, wenn Sie in Rückgabewerte von Funktionen indizieren.
Gnud

3
Oh. in Ordnung. wäre schön gewesen, wenn es möglich wäre.

36
explode() + [0]ist eine langatmige Art zu schreibenstrtok($string, "/")
Mario


292

Die effizienteste Lösung ist die strtokFunktion:

strtok($mystring, '/')

Beispielsweise:

$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home

und

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home

25
Dies ist auch etwa 40% schneller als die current-explodeLösung. (Nicht, dass ich es so oft benutze, dass es wichtig ist.)
Für den

5
Das ist elegant und schnell - sollte die akzeptierte Antwort sein.
Kosta Kontos

5
Dies sollte die ausgenommene Antwort sein. Auf jeden Fall schneller und effizienter mit Speicher- und CPU-Zyklen als jede der angegebenen explodeLösungen.
Shivam Maheshwari

Das Problem mit dem strtokIS first/secondkehrt firstaber /secondzurückkehren , secondanstatt einen leeren String.
Rybo111

Weiter zu meinem obigen Kommentar: Das Verhalten, wenn ein leeres Teil gefunden wurde, hat sich mit PHP 4.1.0 geändert. Das alte Verhalten gab eine leere Zeichenfolge zurück, während das neue, korrekte Verhalten einfach den Teil der Zeichenfolge überspringt
rybo111

95
$first = explode("/", $string)[0];

2
elegant, aber nicht sehr effizient in der Computerzeit. Aber heutzutage kümmern sich die Leute nicht mehr viel um die winzigen CPU-Zyklen
Dennis

13

Was ist damit:

substr($mystring.'/', 0, strpos($mystring, '/'))

Fügen Sie einfach ein '/' am Ende von mystring hinzu, damit Sie sicher sein können, dass es mindestens eines gibt;)


Sie können einfach überprüfen, ob die Zeichenfolge einen Schrägstrich enthält, bevor Sie dies tun. Auf jeden Fall ist es die einfachste Lösung.
Guilherme Sampaio

12

Einzeilige Version der akzeptierten Antwort:

$out=explode("/", $mystring, 2)[0];

Sollte in PHP 5.4+ funktionieren


1
Im Gegensatz zu der folgenden Option begrenzt die "2" die Anzahl der erstellten Array-Elemente. Gute Idee.
Ben in CA

9

Dies ist wahrscheinlich das kürzeste Beispiel, das mir in den Sinn gekommen ist:

list($first) = explode("/", $mystring);

1) list()weist automatisch eine Zeichenfolge zu, bis ein "/"Trennzeichen gefunden wird.
2) Wenn "/"kein Trennzeichen gefunden wird, wird die gesamte Zeichenfolge zugewiesen

... und wenn Sie wirklich von der Leistung besessen sind, können Sie zusätzliche Parameter zum Explodieren hinzufügen, die explode("/", $mystring, 2)das Maximum der zurückgegebenen Elemente begrenzen.


2
Ich mag diesen Ansatz. Spart das Erstellen eines unnötigen Arrays. Und strtok()ist unsicher.
Rybo111

1
@ Rybo111: Worum geht es unsicher strtok()?
hakre

@ rybo111 Ich stimme hakres Gefühl zu; Was macht strtok()unsicher?
Doktor J

@hakre Siehe meine Antworten auf jmarcelis Antwort. Abhängig von der PHP-Version kann dies zu unerwartetem Verhalten führen.
Rybo111

PHP 4.1.0 - rly?
hakre

8

Besser spät als nie. PHP hat dafür eine vordefinierte Funktion. Hier ist dieser gute Weg.

strstr

Wenn Sie das Teil vor dem Match erhalten möchten, setzen Sie einfach before_needle (3. Parameter) auf true http://php.net/manual/en/function.strstr.php

function not_strtok($string, $delimiter)
{    
    $buffer = strstr($string, $delimiter, true);

    if (false === $buffer) {
        return $string;
    }

    return $buffer;
}

var_dump(
    not_strtok('st/art/page', '/')
);

Dies ist nicht sicher zu verwenden, wenn Sie nicht sicher sind, ob die Nadel in der Schnur vorhanden ist.
Fooquency

@fooquency - True, aber Sie können das Zeichen immer am Ende der Zeichenfolge hinzufügen, die Sie überprüfen, nur um sicherzugehen.
MikeSchinkel

Vielen Dank. Meine Tests haben gezeigt, dass strstrdas etwas schneller ist als strtok. Ich werde mit dem ersteren gehen.
Ian Y.

5

Die Funktion strstr () in PHP 5.3 sollte diesen Job ausführen. Der dritte Parameter sollte jedoch auf true gesetzt werden.

Wenn Sie jedoch 5.3 nicht verwenden, sollte die folgende Funktion genau funktionieren:

function strbstr( $str, $char, $start=0 ){
    if ( isset($str[ $start ]) && $str[$start]!=$char ){
        return $str[$start].strbstr( $str, $char, $start+1 );
    }
}

Ich habe es zwar nicht getestet, aber das sollte gut funktionieren. Und es ist auch ziemlich schnell


3
+1 für strstr(), aber beachten Sie, dass es zurückgegeben wird, falsewenn der String nicht enthält. Daher passen $needledie explode()obigen Lösungen in diesem Fall besser.
Benjamin

3

Sie können eine Hilfsfunktion erstellen, um dies zu erledigen:

/**
 * Return string before needle if it exists.
 *
 * @param string $str
 * @param mixed $needle
 * @return string
 */
function str_before($str, $needle)
{
    $pos = strpos($str, $needle);

    return ($pos !== false) ? substr($str, 0, $pos) : $str;
}

Hier ist ein Anwendungsfall:

$sing = 'My name is Luka. I live on the second floor.';

echo str_before($sing, '.'); // My name is Luka

3

Sie können versuchen, einen regulären Ausdruck wie folgt zu verwenden:

$s = preg_replace('|/.*$|', '', $s);

Manchmal sind Regex jedoch langsamer. Wenn also die Leistung ein Problem darstellt, stellen Sie sicher, dass Sie dies richtig bewerten und eine andere Alternative mit Teilzeichenfolgen verwenden, wenn dies für Sie besser geeignet ist.


2
Regex ist wahrscheinlich auch übertrieben, aber da ich dasselbe sage explode, wäre es interessant zu sehen, was schneller ist.
Rvighne

1
Daran ist absolut nichts auszusetzen und ich kann mir nicht vorstellen, warum es 2 Downvotes verdient hätte. Ich persönlich würde Regex nicht verwenden, aber es ist sicherlich nicht falsch.
Billynoah

2

Die Verwendung von currenton explodewürde den Prozess vereinfachen.

 $str = current(explode("/", $str, 2));

0
$string="kalion/home/public_html";

$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));

0

Sie können auch diese einzeilige Lösung verwenden

list($substring) = explode("/", $string);

-1

Ich denke das sollte funktionieren?

substr($mystring, 0, (($pos = (strpos($mystring, '/') !== false)) ? $pos : strlen($mystring)));

Ihre Funktion gibt immer das erste Zeichen zurück, da Sie (strpos ($ mystring, '/')! == false) ausführen, bevor Sie es $ pos zuweisen. Sie müssen ein (($ pos = strpos ($ firstColumnName, '_'))! == false). Dies wäre der 1 Liner, nach dem der Typ sucht, der die Frage gestellt hat.
Mihai P.

-1

warum nicht verwenden:

function getwhatiwant($s)
{
    $delimiter='/';
    $x=strstr($s,$delimiter,true);
    return ($x?$x:$s);
}

ODER:

   function getwhatiwant($s)
   {
       $delimiter='/';
       $t=explode($delimiter, $s);
       return ($t[1]?$t[0]:$s);
   }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.