marie: strpos und 'OR' wie geht das nur?

hi

es geht um folgende Funktion:
int strpos ( string $haystack, mixed $needle [, int $offset] )

$needle darf ja bekanntlich ein einzelnes zeichen oder auch eine zeichenkette sein.

Bsp:
$meinString = 'abcdef';
$findMich   = 'c';
$pos = strpos($meinString, $findMich);

jetzt mein proplem:
ich will im string 'abcdef' die Position des ersten 'c' ODER 'b'
also je nach dem welches zeichen zuerst kommt.

Mit 'OR' geht nicht:
$pos = strpos(abcdef, 'a' OR 'b');

habe schon ne lösung:
  $pos1 = strpos(abcdef, 'a');
  $pos2 = strpos(abcdef, 'b');

//prüfen ob $pos1 oder $pos2 false ist
  //wenn keiner der beiden false ist
  //prüfen welche variable den kleineren wert hat
  if($pos1<$pos2)
    echo $pos1;
  else
    echo $pos2;

das ist ja zugegeben ziemlich umständlich, vorallem wenn es mehr als nur 2 zeichen sind.

Wie geht das besser?
Please Help....
Danke schonmal, marie

  1. Hi,

    Wie geht das besser?

    mit Regular Expressions.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Tach.

      Wie geht das besser?

      mit Regular Expressions.

      Zeig mal!

      --
      Once is a mistake, twice is jazz.
      1. Hi,

        mit Regular Expressions.
        Zeig mal!

        count(preg_split)

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Gsss,

          count(preg_split)

          sollte natürlich strlen sein, nicht count.

          Cheatah

          --
          X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. Tach.

            sollte natürlich strlen sein, nicht count.

            Und vermutlich auch sowas wie strlen(preg_split(...)[0]), falls das Ergebnisarray überhaupt mehr als ein Element hat?

            --
            Once is a mistake, twice is jazz.
            1. Hi,

              Und vermutlich auch sowas wie strlen(preg_split(...)[0]), falls das Ergebnisarray überhaupt mehr als ein Element hat?

              ja, genau, inklusive zugehöriger Variablendeklarationen. Bei dem Anwendungsfall, den der OP andeutete, dürfte das der effizientere Algorithmus sein.

              Cheatah

              --
              X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
              X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
              X-Will-Answer-Email: No
              X-Please-Search-Archive-First: Absolutely Yes
              1. Tach.

                Und vermutlich auch sowas wie strlen(preg_split(...)[0]), falls das Ergebnisarray überhaupt mehr als ein Element hat?

                ja, genau, inklusive zugehöriger Variablendeklarationen. Bei dem Anwendungsfall, den der OP andeutete, dürfte das der effizientere Algorithmus sein.

                Kommt drauf an, woran Du diese Effizienz festmachst. Von der Laufzeit her dürfte das Arbeiten mit RegExps sogar schlechter abschneiden als die Zu-Fuß-Variante (spätestens, wenn man statt foreach in_array benutzt). preg_split erzeugt unnötigerweise ein neues Array mit Teilkopien der Zeichenkette, d. h. mehr Speicherbedarf. Bestimmte Suchzeichen müßten u. U. wegen ihrer Sonderbedeutung im RegExp escaped werden.

                Effizienter würde ich das nicht nennen. Aber solange nicht gerade riesige Zeichenketten nach ebenso vielen Zeichen durchsucht werden, nehmen sich die unterschiedlichen Herangehensweisen wohl nicht viel. :)

                --
                Once is a mistake, twice is jazz.
  2. Tach.

    ich will im string 'abcdef' die Position des ersten 'c' ODER 'b'
    also je nach dem welches zeichen zuerst kommt.

    Wie würdest Du das von Hand (ohne Computer) machen? Vielleicht so: Die Zeichenketten vom Anfang aus schrittweise durchgehen und jeweils überprüfen, ob das aktuelle Zeichen mit einem der gesuchten übereinstimmt. Falls ja, notierst Du die aktuelle Position in der Zeichenkette, und die Suche ist beendet.

    In PHP könnte das in etwa so aussehen:

      
    function strPosMulti ($haystack, $needles) {  
        for ($i = 0; $i < strlen($haystack); $i++) {  
            foreach ($needles as $n) {  
                if ($n == $haystack[$i]) {  
                    return $i;  
                }  
            }  
        }  
        return FALSE;  
    }  
      
      
    $haystack = "lisdhfbfli8zsdtrkubdfg";  
    $needles  = array("3", "c", "f");  
      
    $pos = strPosMulti($haystack, $needles);  
    if ($pos !== FALSE) {  
        echo "gefunden an Position ", $pos;  
    } else {  
        echo "nicht gefunden";  
    }  
    
    
    --
    Once is a mistake, twice is jazz.
    1. ok danke Blaubart,
      so könnt ichs machen.
      Wusste nur nicht das ich eine Variable über einen Index [$i] ansprechen kann wenn es kein array ist.

      Kenne das von c, da wird ein string ja zwangsläufig in einem array gespeichert.

      Gruß

  3. (Hallo|Hi(ho)|Tag) marie,

    hi

    es geht um folgende Funktion:
    int strpos ( string $haystack, mixed $needle [, int $offset] )

    $needle darf ja bekanntlich ein einzelnes zeichen oder auch eine zeichenkette sein.

    Bsp:
    $meinString = 'abcdef';
    $findMich   = 'c';
    $pos = strpos($meinString, $findMich);

    jetzt mein proplem:
    ich will im string 'abcdef' die Position des ersten 'c' ODER 'b'
    also je nach dem welches zeichen zuerst kommt.

    Versuchs mal mit preg_match():

      
    // zwischen den eckigen Klammern sind beliebige Buchstaben ergänzbar  
    $nadel = '/[bc]/';  
    $gefunden = preg_match($nadel, $heuhaufen, $treffer, PREG_OFFSET_CAPTURE);  
    if ($gefunden) {  
      $pos = $treffer[0][1];  
      ...  
    }  
    else {  
      ...  
    }  
    
    

    Bei Suchstrings (also "Nadeln"), die länger als ein Zeichen sind, muss $nadel allerdings etwas abgeändert werden:

      
    $nadel = '/(nadel1|nadel2|nadel3)/';  
    
    

    Hilfreich zum Verständnis von preg_match() und (seinen|ihren) Verwandten ist auf alle Fälle das Kapitel Reguläre Ausdrücke im PHP-Handbuch.
    Empfehlenswert ist das Tutorial zum RegExp-Evaluator.
    Aber auch Wikipedia und Google dürften am Anfang weiterhelfen können.

    Mit 'OR' geht nicht:

    Doch, das ginge auch ...

    $pos = strpos(abcdef, 'a' OR 'b');

    Aber so natürlich nicht. Eher so:

      
    if (  
      ( strpos($heuhaufen, $nadel_a) !== FALSE ) OR  
      ( strpos($heuhaufen, $nadel_b) !== FALSE )  
    ) {  
      // gefunden  
      ...  
    }  
    else {  
      // nicht gefunden  
      ...  
    }  
    
    

    Ich denke aber, dass die Variante mit preg_match() für mehr als zwei Such-Zeichen(ketten) einfacher anzuwenden ist.

    MffG
    EisFuX