PHP: Textteil finden
Gerhard
- php
Hi,
ich möchte aus einem string der Art
'dir/subdir/irgendwas.html'
das 'irgendwas' herausfinden, d.h. der string zwischen '/' und '.'.
Eine unglückliche Lösung für das obige Beispiel habe ich mit
$test = explode('/','dir/subdir/irgendwas.html'); $test = explode('.',$test[2]); echo $test[0];
gefunden.
Allerdings funktioniert die nur weil ich weiß, dass vor dem irgendwas zwei directorys stehen. Es könnten aber mehr oder weniger sein.
Moin Gerhard,
ich möchte aus einem string der Art
'dir/subdir/irgendwas.html'
das 'irgendwas' herausfinden, d.h. der string zwischen '/' und '.'.
Da kommst vielleicht mit basename ein gutes Stück weiter.
Die Kommentare dort erweitern das zu
<?php
// your file
$file = 'image.jpg';
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']);
echo $file_name; // outputs 'image'
?>
Ganz ohne reguläre Ausdrücke 😇
Gruß,
Hallo André,
Warum nicht $info['filename']
?
Edit: Es muss 'filename' sein, alternativ ginge
pathinfo($datei, PATHINFO_FILENAME)
, was den Namen direkt als String liefert.
→ Handbuch
Rolf
Moin Rolf,
Hallo André,
Warum nicht
$info['filename']
?
Ich habe die PHP-Doku zitiert. Du darfst es gerne als PR verbessern.
Edit: Es muss 'filename' sein, alternativ ginge
pathinfo($datei, PATHINFO_FILENAME)
, was den Namen direkt als String liefert.→ Handbuch
Meine Überlegung war, die Struktur eines Dateipfades hier zum Vorteil zu nutzen.
Gruß,
@@Gerhard
Eine unglückliche Lösung für das obige Beispiel habe ich mit
$test = explode('/','dir/subdir/irgendwas.html'); $test = explode('.',$test[2]); echo $test[0];
gefunden.
Allerdings funktioniert die nur weil ich weiß, dass vor dem irgendwas zwei directorys stehen. Es könnten aber mehr oder weniger sein.
In JavaScript bekommt man mit dem Index −1 das letzte Element, mit −2 das vorletzte usw.:
const mainCharacters = [
'James T. Kirk',
'Spock',
'Leonard “Bones” McCoy',
];
console.log(mainCharacters.at(-1)); // "Leonard “Bones” McCoy"
console.log(mainCharacters.at(-2)); // "Spock"
In PHP gibt es das nicht?
(Nicht, dass man das in diesem Fall bräuchte, wie @Ryuno-Ki schon sagte.)
🖖 Live long and prosper
Nachtrag: Gibt’s: mit count()
. $test[count($test) - 1]
sollte das letzte Element liefern.
Hallo Gerhard,
Dein Problem kann leicht gelöst werden. Versuch es doch mal mit strrpos (von rechts den ersten Fund suchen):
$str_pfad = 'dir/subdir/irgendwas.html';
$str_ergebnis = substr($str_pfad, strrpos($str_pfad,"/")+1);
siehe
Hallo Hans,
danke für die Idee mit strrpos, die hat mich zumindest auf den Gedanken gebracht, dass "foo/bar/" in $str_path Beachtung verdient.
Aber es gibt's die Minus-Bewertungen, weil
dir/subdir/datei.ext
, aber eine Logik zum Extrahieren des Dateinamens sollte den Pfad trotzdem nicht als gegeben voraussetzen.Rolf
Hi,
Ergebnis: "irgendwas.html" aber nicht das gewünschte "irgendwas"
Hallo,
tatsächlich ist das Problem MÖGLICHERWEISE mit Hans' Ansatz besser gelöst als mit pathinfo. Der Ansatz, nicht das, was er gezeigt hat. Das ist buggy.
Denn:
pathinfo("bla/foo/datei.txt", PATHINFO_FILENAME)
liefert "datei"
, was richtig ist.
Aber
pathinfo("bla/foo/", PATHINFO_FILENAME)
liefert "foo"
, und über diese Richtigkeit kann man sich streiten, denn unter "bla/foo/"
versteht man eigentlich keine Datei, sondern ein Verzeichnis.
Der strrpos
-Vorschlag von Hans liefert einen Leerstring. Allerdings muss noch nachgebessert werden, denn Gerhard will ja den Teil ab dem Punkt nicht mehr haben und wenn gar kein Pfadanteil im Dateinamen ist, verwirft Hans den ersten Teil vom Dateinamen. Das zu fixen überlasse ich dem Autor 😉
Aus meiner Sicht ist hier eine Regex brauchbar. Eigentlich ist das schade, denn pathinfo() sollte erkennen, dass sein Parameter auf den Directory Separator endet und dann keinen Dateinamen liefern. Finde ich.
Mein Regex-Vorschlag wäre:
$success = preg_match('/^(?:.*\\'.DIRECTORY_SEPARATOR.')?' .
'(?<name>[^.]*)(?:\\..*)?$/',
$datei, $info);
// oder ausführlicher
$success = preg_match('/^(?<pfad>.*\\'.DIRECTORY_SEPARATOR.')?' .
'(?<name>[^.]*)(?<extension>\\..*)?$/',
$datei, $info);
// und dann:
$dateiname = $info['name'];
(Umbrüche und Aufteilung der Regex in 2 Strings, damit man das im Forum besser lesen kann)
Die erste Version extrahiert nur den Namen, die zweite Version stellt auch Pfad und Erweiterung in Matchgruppen bereit. Ich habe tatsächlich keine Ahnung, mit welchem String man diese Regex zum Nicht-Matchen bringen könnte, so dass $success==0 herauskommt. Bei einem Leerstring als Input kommt halt ein leerer Name heraus. Möchte man sofort informiert sein, wenn der Name ein Leerstring ist, dann kann man in der name-Gruppe aus dem * ein + machen, in diesem Fall würde $success==0 herauskommen, wenn der Name leer ist (wie z.B. in foo/dat/
, aber auch in .htaccess
.
Rolf
Moin Rolf,
Aus meiner Sicht ist hier eine Regex brauchbar. Eigentlich ist das schade, denn pathinfo() sollte erkennen, dass sein Parameter auf den Directory Separator endet und dann keinen Dateinamen liefern. Finde ich.
Na ja, es ließe sich ja auch ein if
auf „endet mit DIRECTORY_SEPARATOR
” voranstellen.
Ich mag gerne ReDoS vermeiden, wenn es geht. Hat sogar schon so Cloud-Provider in die Knie gezwungen, weil die falsche Engine eingesetzt wurde. Muss nicht sein.
Gruß,
Hallo zusammen,
"jetzt sehe ich vor lauter Bäumen den Wald nicht mehr."
Kann mir jemand schreiben, welches die beste Variante ist?
@@Gerhard
Kann mir jemand schreiben, welches die beste Variante ist?
Ich würde denken, die am besten bewertete.
🖖 Live long and prosper
Kann mir jemand schreiben, welches die beste Variante ist?
Ich würde denken, die am besten bewertete.
Wie finde ich die am besten bewertete?
@@Gerhard
Kann mir jemand schreiben, welches die beste Variante ist?
Ich würde denken, die am besten bewertete.
Wie finde ich die am besten bewertete?
In der Übersicht:
Die Zahlen vor den Postings geben die Bewertung an.
Oder du folgst diesem Link.
🖖 Live long and prosper
Hallo Gunnar,
Dann mach ich da mal schnell noch ein - dazu. Das Beispiel, das André da zitiert, ist unnötig kompliziert.
pathinfo($datei, PATHINFO_FILENAME)
liefert den gewünschten Teil direkt als String.
Außer bei "foo/", das muss man separat abfragen (oder meine Regex nehmen, wobei ich André insofern zustimme, dass Regexe den Server stärker belastet, man die also sparsam einsetzen sollte).
Dieses Gefummel mit basename ist jedenfalls Quatsch, das Beispiel taugt nichts. Vielleicht ging da vor 15 Jahren nicht anders, aber oft sind solche Userbeispiele auch einfach nur Unsinn. Ich habe es runtergevotet.
Rolf
Hallo,
ich sehe hier die unterschiedlichsten Vorschläge zur Ermittlung eines Pfades eines vorgegebenen Dateinamens.
Mein Problem war aber ein ganz anderes, nämlich wie erhalte ich einen bestimmten Teil aus einem String.
Hallo Gerhard,
Jein. Wir wir geantwortet haben, liegt an der Art, wie Du dein Problem beschrieben hast:
ich möchte aus einem string der Art
'dir/subdir/irgendwas.html'
das 'irgendwas' herausfinden, d.h. der string zwischen '/' und '.'.
Das ist bei uns so angekommen, dass Du aus einem Dateipfad den Namen der Datei ohne Extension herauslösen möchtest. Und dafür haben wir Lösungen angeboten, dafür ist pathinfo($datei, PATHINFO_FILENAME)
die einfachste Methode.
Wenn das nur ein Beispiel war und Du eine generellere Lösung brauchst, die über unsere angenommene Anwendung hinausgeht, dann bitte ich Dich, die Problemstellung in der erforderlichen Allgemeinheit zu beschreiben.
Rolf
Mein Problem war aber ein ganz anderes, nämlich wie erhalte ich einen bestimmten Teil aus einem String.
Kurze Antwort: Man lässt alles unerwünschte/überflüssige weg. Wie man das genau macht hängt davon ab, wie der Teil definiert oder beschrieben werden kann, welcher der „bestimmte“ sein soll oder wegzulassen ist. Und davon, ob der „Heuhaufen“ (Du suchst die „Nadel“) einen bestimmten Aufbau hat.