Funktion strspn() - Anzahl übereinstimmender Zeichen zu Beginn eines strings

In PHP-Anwendungen werden häufig Zeichenketten miteinander verglichen, um bestimmte Informationen über sie zu erhalten. Eine mögliche Information kann dabei die Anzahl von Zeichen eines strings sein, die von Beginn an nur aus Zeichen besteht, die man vorgegeben hat. Für solche Aufgaben kann man die Funktion strspn() verwenden. Hierbei übergibt man eine Maske aus Zeichen, die in einem string von Beginn an gezählt werden sollen. Die Zählung erfolgt solange, bis ein Zeichen auftritt, das nicht in der Suchmaske enthalten ist. Innerhalb der runden Klammern werden die folgenden Parameter angegeben.

  1. Der zu durchsuchende string (subject).
  2. Die Maske mit den Zeichen, die gezählt werden sollen (mask).
  3. Die Startposition, ab der die Zeichenkette durchsucht werden soll (start, optional).
  4. Die Länge des Abschnitts, der durchsucht werden soll (length, optional).

Der Rückgabewert ist eine Ganzzahl (Datentyp int). Beim folgenden Beispiel erhält man als Rückgabewert die Zahl 5, da die ersten 5 Zeichen der Zeichenkette aus den Ziffern 0 bis 9 bestehen. Beim Vorkommen des Buchstaben M wird der Vorgang beendet. Die Reihenfolge der Zeichen, die als Maske übergeben werden, spielt dabei keine Rolle.

<?php

$str = '01234Mustertext';
$maske = '9876543210';

// Ausgabe 5
echo strspn($str, $maske);

?>

Startposition für die Zählung festlegen

Soll die Zählung nicht von Beginn an durchgeführt werden, kann man als dritten Parameter die Startposition festlegen. Beim folgenden Beispiel beginnt die Zählung mit dem 2. Zeichen, sodass der Rückgabewert eine 4 ist.

<?php

$str = '01234Mustertext';
$maske = '9876543210';
$start = 1;

// Ausgabe 4
echo strspn($str, $maske, $start);

?>

Maximale Länge des zu zählenden Abschnitts festlegen

Es ist auch möglich, die maximale Länge des zu zählenden Abschnitts festzulegen. Beim folgenden Beispiel beginnt die Zählung mit dem 2. Zeichen und ist maximal 3 Zeichen lang, sodass der Rückgabewert die Zahl 3 ist.

<?php

$str = '01234Mustertext';
$maske = '9876543210';
$start = 1;
$laenge = 3;

// Ausgabe 3
echo strspn($str, $maske, $start, $laenge);

?>

Übereinstimmende Zeichen in Verbindung mit strlen() nutzen

Mit der Funktion strlen() oder mb_strlen() für Unicode-Zeichen kann man die Länge einer Zeichenkette ermitteln. In Verbindung mit der Funktion strspn() kann man ermitteln, ob eine Zeichenkette nur aus bestimmten Zeichen besteht. So kann man z.B. überprüfen, ob die Zeichenkette nur aus Ziffern besteht.

<?php

$str = '01234987654321';
$maske = '0123456789';

if (strlen($str) != strspn($str, $maske))
{
  echo 'Telefonnummer nicht ok';
}
else
{
  echo 'Telefonnummer ok';
}

?>

Solche Prüfungen werden normalerweise mit sogenannten PCRE-Funktionen wie preg_match() durchgeführt. Der Nachteil hierbei ist jedoch die Geschwindigkeit, da sie rechenintensiv sind. Mit strlen() und strspn() ist das deutlich schneller.

Zählung bei Multibyte-Zeichen wie z.B. Umlauten in UTF-8

Aus technischer Sicht werden nicht die Anzahl der Zeichen gezählt, sondern die Anzahl der Bytes, die diese belegen. Dabei wird davon ausgegangen, dass 1 Zeichen 1 Byte belegt. Das ist jedoch nicht immer der Fall. Wie viele Bytes ein Zeichen belegt, hängt nämlich unter anderem von der Zeichenkodierung ab. Beispielsweise belegen die Umlaute in UTF-8 zwei Bytes, in ISO-8859-1 jedoch nur 1 Byte. Das kann beim Einsatz von strspn() zu falschen Zählungen führen. Beim folgenden Beispiel ist der Rückgabewert 6, obwohl eigentlich nur die ersten 3 Zeichen übereinstimmen.

<?php

$str = 'äöü01234Mustertext';
$maske = 'äöü';

// Ausgabe 6
echo strspn($str, $maske);

?>

Eigene Multibyte-Funktion mit Berücksichtigung der Zeichenkodierung

Es gibt gemäß dem Stand von 03/2016 keine interne Multibyte-Funktion für strspn(), mit der man in einer Zeichenkette die Anzahl der Zeichen aus einer Maske zählen kann. Falls man so eine Funktion trotzdem benötigt, kann man eine eigene Funktion schreiben. Eine mögliche Lösung kann die Funktion mb_strspn() im folgenden Code sein. Wichtig ist bei dem Code, dass die einzelnen Zeichen der Maske als Array übergeben werden. Außerdem muss die PHP-Datei auch mit der angegebenen Zeichenkodierung gespeichert werden.

<?php

function mb_strspn 
(
$str, 
$maske, 
$start = 0, 
$length = NULL, 
$encoding = 'UTF-8'
)
{
  $str = mb_substr ($str, $start, $length, $encoding);
  $count = 0;
  $checkstr = mb_substr($str, $count, 1, $encoding);

  while (in_array ($checkstr, $maske) == TRUE)
  {
    $count++;
    $checkstr = mb_substr($str, $count, 1, $encoding);
  }
  return $count;
}

$str = 'äöü01234Mustertext';
$maske = array ('ä', 'ö', 'ü');
$start = 1;

echo mb_strspn($str, $maske, $start);

?>

Zunächst werden mit $str, $maske, $start, $length und $encoding die Parameter festgelegt, wobei die letzten drei mit Standardwerten vorbelegt werden, damit diese im Falle einer Nichtangabe verwendet werden.

Mit der Funktion mb_substr() wird unter Berücksichtigung der Zeichenkodierung der Teil der Zeichenkette herausgelöst, der mit $start beginnt und so lang ist wie mit $length angegeben. Mit $encoding wird die Zeichenkodierung für den string angegeben. Dazu wird als nächster Schritt die Zählvariable $count auf 0 gesetzt.

Danach wird mit der Funktion mb_substr() das erste Zeichen aus dem Teil-String herausgelöst und in der Variable $checkstr gespeichert. Mit der while-Schleife wird überprüft, ob das Zeichen im Array $maske enthalten ist. Falls das der Fall ist, wird die Zählvariable $count um 1 hochgezählt und das nächste Zeichen aus dem Teil-String wird in der Variable $checkstr gespeichert.

Die while-Schleife sorgt dafür, dass die Zählvariable solange hochgezählt wird, bis ein Zeichen vorkommt, das nicht im Array $maske enthalten ist und die Schleife beendet. Um zu überprüfen, ob das Zeichen im Array $maske enthalten ist, wird die Funktion in_array() verwendet. So hätte man eine Funktion wie strspn(), bei der die Zeichenkodierung berücksichtigt wird.

Die Variable $count ist der Rückgabewert der Funktion, in dem die Zählung gespeichert wird.

Zum Schluss des Codes erfolgt ein Test, bei dem die Ausgabe die Zahl 2 ist. Das erste Zeichen wird praktisch übersprungen und danach folgen zwei Zeichen aus der Maske, die in der Zeichenkette vorhanden sind. Die Werte für $length und $encoding wurden nicht übergeben, sodass die Standardwerte gelten. Man hätte sie jedoch auch angeben können.