Michi: Einen Teil aus einem String ausschneiden

Ich möchte aus einem String etwas herausschneiden, was zwischen zwei bestimmten Marken steht. In diesem Fall <b> </b>. Es gibt ja mehrere Möglichkeiten ans Ziel zu kommen. Ich habe es mit explode realisiert. Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

$string ='Es war einmal vor langer Zeit in einem <b>fernen</b> Land';	
$start 	='<b>';	
$ende 	='</b>';	


$part 		= explode($start, $string);		// vor 	<b> abschneiden
$ergebnis 	= explode($ende,$part[1]);		// nach </b> abschneiden

echo $ergebnis[0];
  1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

    Ich möchte aus einem String etwas herausschneiden, was zwischen zwei bestimmten Marken steht. In diesem Fall <b> </b>. Es gibt ja mehrere Möglichkeiten ans Ziel zu kommen. Ich habe es mit explode realisiert. Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

    $string ='Es war einmal vor langer Zeit in einem <b>fernen</b> Land';	
    $start 	='<b>';	
    $ende 	='</b>';	
    
    
    $part 		= explode($start, $string);		// vor 	<b> abschneiden
    $ergebnis 	= explode($ende,$part[1]);		// nach </b> abschneiden
    
    echo $ergebnis[0];
    

    Du machst dass schon ganz gut. Füge aber eine Fehlerbehandlung ein. Und bedenke, was Du machen willst, wenn mehrere Bereiche mit <b>TEXT</b> im Quellstring enthalten sind.

    Als Alternative kannst Du auch strstr() oder stristr() benutzen. Zweiteres hat auch gegenüber explode() den Vorteil, dass es unempfindlich gegen Groß/Kleinschreibung ist.

    Du musst dann nur noch den String kürzen um das vorangestellte <b>.

    Spirituelle Grüße
    Euer Robert
    robert.r@online.de

    --
    Möge der wahre Forumsgeist ewig leben!
  2. Hallo Michi,

    Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

    falls du regex einfacher findest, koennte man das zB auch so machen:

    if(preg_match('~<b>(.*?)</b>~', $string, $out))
      echo $out[1];
    

    Das Suchmuster <b>(.*?)</b> steht zwischen sog. Delimitern deiner Wahl. $out[0] im Ergebnis entspricht jeweils dem, was das gesamte Suchmuster findet, $out[1] dem ersten geklammerten Subpattern usw.

    . ist der "Joker" fuer jedes Zeichen (default ausser newline). Der Quantifier * steht fuer beliebig viele. Da standardmaessig Gier vorherrscht und der Parser ev. auch </b> verschlingen moechte, kann man durch ein Fragezeichen nach dem Stern-Quantifier Bescheidenheit erzwingen.

    Generell wird nicht empfohlen html mit regex zu parsen.

    Viel Erfolg, Jonny 5

    1. @@Jonny 5

      Das Suchmuster <b>(.*?)</b>

      erkennt <b foo="bar">baz</b> nicht.

      Generell wird nicht empfohlen html mit regex zu parsen.

      „Generell wird davon abgeraten“ trifft es besser.

      LLAP

      --
      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
      1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

        Das Suchmuster <b>(.*?)</b>

        erkennt <b foo="bar">baz</b> nicht.

        Generell wird nicht empfohlen html mit regex zu parsen.

        „Generell wird davon abgeraten“ trifft es besser.

        Das ist ja der Grund, warum ich mich hier durch PHP-DOMDocument quäle.

        Der Parser funktioniert sehr gut, nur die vorhandenen Mehthoden sind noch sehr rudimentär. Zum Auffinden der gewünschten Nodes benötigt man noch ein paar mehr Möglichkeiten. Und das Einfügen von Nodes ist noch möglich, ohne dass eine logische Kontrolle stattfindet. Man kann also noch ohne weiteres ein <div> in ein <p> einfügen.

        Aber ein getElementsByName('b') ist schon im Standardumfang vorhanden.

        Nun frage ich mich, was mehr mit Kanonen auf Spatzen ist: die RegExMaschine oder der DOMDocument-Parser?

        Spirituelle Grüße
        Euer Robert
        robert.r@online.de

        --
        Möge der wahre Forumsgeist ewig leben!
  3. Tach!

    Ich möchte aus einem String etwas herausschneiden, was zwischen zwei bestimmten Marken steht. [...] Ich habe es mit explode realisiert. Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

    Ein regulärer Ausdruck. Finde die Startsequenz, dann nimm alles mit, gefolgt von der Ende-Sequenz, und das bitte ungreedy (nicht gierig). Das setzt voraus (genauso wie Stringfunktionen), dass die beiden Sequenzen immer genau so notiert sind und nicht von den vielfältigen Möglichkeiten HTMLs Gebrauch machen.

    dedlfix.

    1. @@dedlfix

      Ich möchte aus einem String etwas herausschneiden, was zwischen zwei bestimmten Marken steht. [...] Ich habe es mit explode realisiert. Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

      Ein regulärer Ausdruck.

      Wirklich?

      und das bitte ungreedy (nicht gierig).

      <b>foo <b>bar</b> baz</b>

      Du möchtest <b>foo <b>bar extrahieren?

      Das setzt voraus (genauso wie Stringfunktionen), dass die beiden Sequenzen immer genau so notiert sind und nicht von den vielfältigen Möglichkeiten HTMLs Gebrauch machen.

      Eben. Und diese Voraussetzung kann nicht garantiert werden.

      Es ist wohl nie eine gute Idee, einen regulären Ausdruck auf Markup loszulassen.

      LLAP

      --
      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
      1. Tach!

        Ein regulärer Ausdruck.

        Wirklich?

        Ja klar, passt auf den geschilderten Fall.

        <b>foo <b>bar</b> baz</b>

        Du möchtest <b>foo <b>bar extrahieren?

        Das ist dein Fall, nicht der geschilderte.

        Das setzt voraus (genauso wie Stringfunktionen), dass die beiden Sequenzen immer genau so notiert sind und nicht von den vielfältigen Möglichkeiten HTMLs Gebrauch machen.

        Eben. Und diese Voraussetzung kann nicht garantiert werden.

        Wer sagt das? Gesucht war keine allgemeingültige Lösung, sondern eine für das Problem.

        Es ist wohl nie eine gute Idee, einen regulären Ausdruck auf Markup loszulassen.

        Sag nie nie.

        dedlfix.

      2. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

        @@dedlfix

        Ich möchte aus einem String etwas herausschneiden, was zwischen zwei bestimmten Marken steht. [...] Ich habe es mit explode realisiert. Gibt es vieleicht etwas einfacheres, das zu bewerkstelligen?

        Ein regulärer Ausdruck.

        Wirklich?

        und das bitte ungreedy (nicht gierig).

        <b>foo <b>bar</b> baz</b>

        Du möchtest <b>foo <b>bar extrahieren?

        Das setzt voraus (genauso wie Stringfunktionen), dass die beiden Sequenzen immer genau so notiert sind und nicht von den vielfältigen Möglichkeiten HTMLs Gebrauch machen.

        Erstmal gefragt: ist diese Schachtelung zulässig?
        Sinnvoll ist sie ja wohl nicht, es sei denn, dass man mit jedem <b> eine Stufe fetter anzeigen lassen wollte... so wie das bei <bier> ist ;-)

        Als zweites gefragt; was würdest Du hier selektieren wollen? den gesamten Bereich zwischen dem ersten <b> und dem letzten </b> (die Attribute lasse ich jetzt extra erst einmal beiseite)?

        Ich frag Dich das, weil ich gerade an entsprechenden Methoden/Funktionen sitze, um diese Dinge mit dem DOM-Parser zu behandeln. Meine derzeitige (reduzierte) Array-Darstellung sieht z.B. so aus:

        	<td><b>2-2<b>-Eins </b>Nööö</b></td>
        
                                            [1: td] => Array
                                                (
                                                    [nodetype] => 1
                                                    [nodename] => td
                                                    [lineno] => 85
                                                    [childcount] => 1
                                                    [1: b] => Array
                                                        (
                                                            [nodetype] => 1
                                                            [nodename] => b
                                                            [lineno] => 85
                                                            [childcount] => 3
                                                            [1: #text] => Array
                                                                (
                                                                    [nodetype] => 3
                                                                    [nodename] => #text
                                                                    [lineno] => 85
                                                                    [value] => 2-2
                                                                )
        
                                                            [2: b] => Array
                                                                (
                                                                    [nodetype] => 1
                                                                    [nodename] => b
                                                                    [lineno] => 85
                                                                    [childcount] => 1
                                                                    [1: #text] => Array
                                                                        (
                                                                            [nodetype] => 3
                                                                            [nodename] => #text
                                                                            [lineno] => 85
                                                                            [value] => -Eins
                                                                        )
        
                                                                )
        
                                                            [3: #text] => Array
                                                                (
                                                                    [nodetype] => 3
                                                                    [nodename] => #text
                                                                    [lineno] => 85
                                                                    [value] => Nööö
                                                                )
        
                                                        )
        
                                                )
        
        

        Da man das Array nur zur bequemen Visualisierung benötigt, musst Du dich bitte nicht über die Bezeichner [1: td] usw wundern. Die machen nur die Ansicht kompakter. Für die Methoden und Funktionen hat man sowieso schon den Objektbaum, den kann ich hier aber noch nicht darstellen. Das ist eines der Ziele!

        Ich würde die Sinnhaftigkeit von Anwendungsfällen gerne etwas diskutieren, um eine Marschrichtung für die Funktionen/Methoden zu bekommen. Wonach würden Programmierer suchen in einem HTML-Dokument und was würden sie damit anfangen wollen?

        Hier war die Aufgabenstellung: "alles, was zwischen zwei bestimmten Textmarken steht (in einem größeren Text) ausschneiden". Da ist freilich die Aufgabenstellung schon sehr unpräzise, wenn man sie auf HTML anwendet.

        Spirituelle Grüße
        Euer Robert
        robert.r@online.de

        --
        Möge der wahre Forumsgeist ewig leben!
        1. @@robertroth

          <b>foo <b>bar</b> baz</b> Erstmal gefragt: ist diese Schachtelung zulässig?

          Ja. Warum auch nicht?

          Sinnvoll ist sie ja wohl nicht

          Nicht?

          es sei denn, dass man mit jedem <b> eine Stufe fetter anzeigen lassen wollte...

          Bis auf den Default im Browserstylesheet hat das b-Element nichts mit fett zu tun: “The b element represents a span of text to which attention is being drawn for utilitarian purposes without conveying any extra importance and with no implication of an alternate voice or mood, such as key words in a document abstract, product names in a review, actionable words in interactive text-driven software, or an article lede.”

          <b>foo <b>bar</b> baz</b> Als zweites gefragt; was würdest Du hier selektieren wollen?

          Zum ersten „foo bar baz“, zum zweiten „bar“.

          LLAP

          --
          „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
  4. Hallo,

    Ich möchte aus einem String etwas herausschneiden,

    du hast selber eine funktionierende Lösung, die anderen Poster haben Alternativen gezeigt.

    Jetzt kommts ein bisschen drauf an, welche anderen Fälle du berücksichtigen willst, d.h. wie dein Fall allgemeiner aussieht.

    Gruß
    Kalk