String-Funktionen
Nette\Utils\Strings ist eine statische Klasse mit nützlichen Funktionen für die Arbeit mit Strings in UTF-8-Kodierung.
Installation:
composer require nette/utils
Alle Beispiele setzen voraus, dass dieser Klassen-Alias definiert ist:
use Nette\Utils\Strings;
Groß-/Kleinschreibung
Diese Funktionen erfordern die PHP-Erweiterung mbstring.
lower (string $s): string
Wandelt einen UTF-8-String in Kleinbuchstaben um.
Strings::lower('Hello World'); // 'hello world'
upper (string $s): string
Wandelt einen UTF-8-String in Großbuchstaben um.
Strings::upper('Hello World'); // 'HELLO WORLD'
firstUpper (string $s): string
Wandelt das erste Zeichen eines UTF-8-Strings in einen Großbuchstaben um und lässt die übrigen Zeichen unverändert.
Strings::firstUpper('hello world'); // 'Hello world'
firstLower (string $s): string
Wandelt das erste Zeichen eines UTF-8-Strings in einen Kleinbuchstaben um und lässt die übrigen Zeichen unverändert.
Strings::firstLower('Hello world'); // 'hello world'
capitalize (string $s): string
Wandelt das erste Zeichen jedes Wortes in einem UTF-8-String in einen Großbuchstaben um und die übrigen in Kleinbuchstaben.
Strings::capitalize('hello world'); // 'Hello World'
Bearbeiten eines Strings
normalize (string $s): string
Entfernt Steuerzeichen, vereinheitlicht die Zeilenenden zu \n, entfernt leere Zeilen am Anfang und am Ende,
entfernt Leerzeichen am Zeilenende und normalisiert UTF-8 in die Normalform NFC.
unixNewLines (string $s): string
Wandelt die Zeilenenden in das auf Unix-Systemen verwendete \n um. Als Zeilenenden gelten: \n,
\r, \r\n, U+2028 Zeilentrenner, U+2029 Absatztrenner.
$unixLikeLines = Strings::unixNewLines($string);
platformNewLines (string $s): string
Wandelt die Zeilenenden in die Zeichen um, die für die aktuelle Plattform typisch sind, also \r\n unter Windows
und \n anderswo. Als Zeilenenden gelten: \n, \r, \r\n, U+2028 Zeilentrenner,
U+2029 Absatztrenner.
$platformLines = Strings::platformNewLines($string);
webalize (string $s, ?string $charlist=null, bool $lower=true): string
Bringt einen UTF-8-String in die in URLs verwendete Form, entfernt also Diakritika und ersetzt alle Zeichen außer den Buchstaben des englischen Alphabets und Ziffern durch Bindestriche.
Strings::webalize('žluťoučký kůň'); // 'zlutoucky-kun'
Sollen weitere Zeichen erhalten bleiben, lassen sie sich im zweiten Parameter angeben.
Strings::webalize('10. image_id', '._'); // '10.-image_id'
Der dritte Parameter kann die Umwandlung in Kleinbuchstaben unterdrücken.
Strings::webalize('Dobrý den', null, false); // 'Dobry-den'
Erfordert die PHP-Erweiterung intl.
trim (string $s, string $charlist=self::TrimCharacters): string
Entfernt Leerraum (oder andere im zweiten Parameter angegebene Zeichen) am Anfang und am Ende eines UTF-8-Strings.
Strings::trim(' Hello '); // 'Hello'
truncate (string $s, int $maxLen,
string $append=`'…'`): string
Kürzt einen UTF-8-String auf die angegebene Maximallänge und versucht dabei, ganze Wörter zu erhalten. Wird der String gekürzt, werden am Ende Auslassungspunkte angehängt (über den dritten Parameter änderbar).
$text = 'Hello, how are you today?';
Strings::truncate($text, 5); // 'Hell…'
Strings::truncate($text, 20); // 'Hello, how are you…'
Strings::truncate($text, 30); // 'Hello, how are you today?'
Strings::truncate($text, 20, '~'); // 'Hello, how are you~'
indent (string $s, int $level=1, string
$chars=`"\t"`): string
Rückt einen mehrzeiligen Text von links ein. Der zweite Parameter gibt die Anzahl der Einrückungszeichen an, der dritte das Zeichen bzw. die Zeichen, mit denen eingerückt wird (standardmäßig ein Tabulator).
Strings::indent('Nette'); // "\tNette"
Strings::indent('Nette', 2, '+'); // '++Nette'
padLeft (string $s, int $length, string
$pad=`' '`): string
Füllt einen UTF-8-String auf die angegebene Länge auf, indem der String $pad von links vorangestellt wird.
Strings::padLeft('Nette', 6); // ' Nette'
Strings::padLeft('Nette', 8, '+*'); // '+*+Nette'
padRight (string $s, int $length,
string $pad=`' '`): string
Füllt einen UTF-8-String auf die angegebene Länge auf, indem der String $pad von rechts angehängt wird.
Strings::padRight('Nette', 6); // 'Nette '
Strings::padRight('Nette', 8, '+*'); // 'Nette+*+'
substring (string $s, int $start, ?int $length=null): string
Gibt den Teil des UTF-8-Strings $s zurück, der durch die Startposition $start und die Länge
$length bestimmt ist. Ist $start negativ, beginnt der zurückgegebene String beim
$start-ten Zeichen vom Ende.
Strings::substring('Nette Framework', 0, 5); // 'Nette'
Strings::substring('Nette Framework', 6); // 'Framework'
Strings::substring('Nette Framework', -4); // 'work'
reverse (string $s): string
Kehrt einen UTF-8-String um.
Strings::reverse('Nette'); // 'etteN'
length (string $s): int
Gibt die Anzahl der Zeichen (nicht Bytes) in einem UTF-8-String zurück.
Das ist die Anzahl der Unicode-Codepunkte, die sich von der Anzahl der Grapheme unterscheiden kann.
Strings::length('Nette'); // 5
Strings::length('červená'); // 7
startsWith (string $haystack, string $needle): bool
Prüft, ob der String $haystack mit dem String $needle beginnt.
$haystack = 'Starts';
$needle = 'St';
Strings::startsWith($haystack, $needle); // true
Verwenden Sie die native Funktion str_starts_with().
endsWith (string $haystack, string $needle): bool
Prüft, ob der String $haystack mit dem String $needle endet.
$haystack = 'Ends';
$needle = 'ds';
Strings::endsWith($haystack, $needle); // true
Verwenden Sie die native Funktion str_ends_with().
contains (string $haystack, string $needle): bool
Prüft, ob der String $haystack den String $needle enthält.
$haystack = 'Auditorium';
$needle = 'dit';
Strings::contains($haystack, $needle); // true
Verwenden Sie die native Funktion str_contains().
compare (string $left, string $right, ?int $length=null): bool
Vergleicht zwei UTF-8-Strings oder Teile davon, ohne auf die Groß-/Kleinschreibung zu achten. Ist $length gleich
null, werden die ganzen Strings verglichen. Ist der Wert negativ, wird die entsprechende Anzahl von Zeichen vom Ende der Strings
verglichen, sonst die entsprechende Anzahl von Zeichen vom Anfang.
Strings::compare('Nette', 'nette'); // true
Strings::compare('Nette', 'next', 2); // true - die ersten 2 Zeichen stimmen überein
Strings::compare('Nette', 'Latte', -2); // true - die letzten 2 Zeichen stimmen überein
findPrefix (array $strings): string
Findet das gemeinsame Präfix der Strings. Gibt einen leeren String zurück, wenn kein gemeinsames Präfix gefunden wird.
Strings::findPrefix(['prefix-a', 'prefix-bb', 'prefix-c']); // 'prefix-'
Strings::findPrefix(['Nette', 'is', 'great']); // ''
before (string $haystack, string $needle, int $nth=1): ?string
Gibt den Teil des Strings $haystack vor dem $nth-ten Vorkommen des Strings $needle
zurück. Gibt null zurück, wenn $needle nicht gefunden wird. Ist $nth negativ, wird vom
Ende des Strings aus gesucht.
Strings::before('Nette_is_great', '_', 1); // 'Nette'
Strings::before('Nette_is_great', '_', -2); // 'Nette'
Strings::before('Nette_is_great', ' '); // null
Strings::before('Nette_is_great', '_', 3); // null
after (string $haystack, string $needle, int $nth=1): ?string
Gibt den Teil des Strings $haystack nach dem $nth-ten Vorkommen des Strings $needle
zurück. Gibt null zurück, wenn $needle nicht gefunden wird. Ist $nth negativ, wird vom
Ende des Strings aus gesucht.
Strings::after('Nette_is_great', '_', 2); // 'great'
Strings::after('Nette_is_great', '_', -1); // 'great'
Strings::after('Nette_is_great', ' '); // null
Strings::after('Nette_is_great', '_', 3); // null
indexOf (string $haystack, string $needle, int $nth=1): ?int
Gibt die Zeichenposition des $nth-ten Vorkommens des Strings $needle im String $haystack
zurück. Gibt null zurück, wenn $needle nicht gefunden wird. Ist $nth negativ, wird vom
Ende des Strings aus gesucht.
Strings::indexOf('abc abc abc', 'abc', 2); // 4
Strings::indexOf('abc abc abc', 'abc', -1); // 8
Strings::indexOf('abc abc abc', 'd'); // null
Kodierung
fixEncoding (string $s): string
Entfernt ungültige UTF-8-Zeichen aus einem String.
$correctString = Strings::fixEncoding($invalidString);
checkEncoding (string $s): bool
Prüft, ob ein String ein gültiger UTF-8-String ist.
$isUtf8 = Strings::checkEncoding($string);
Verwenden Sie Nette\Utils\Validators::isUnicode().
toAscii (string $s): string
Wandelt einen UTF-8-String in ASCII um, entfernt also Diakritika und so weiter.
Strings::toAscii('žluťoučký kůň'); // 'zlutoucky kun'
Erfordert die PHP-Erweiterung intl.
chr (int $code): string
Gibt zu einem Codepunkt (einer Zahl im Bereich 0×0000..D7FF oder 0xE000..10FFFF) das entsprechende Zeichen in UTF-8 zurück.
Strings::chr(0xA9); // '©' in UTF-8-Kodierung
ord (string $c): int
Gibt den Codepunkt eines bestimmten Zeichens in UTF-8 zurück (eine Zahl im Bereich 0×0000..D7FF oder 0xE000..10FFFF).
Strings::ord('©'); // 169 (0xA9)
Reguläre Ausdrücke
Die Klasse Strings bietet Funktionen für die Arbeit mit regulären Ausdrücken. Anders als die nativen
PHP-Funktionen haben sie eine verständlichere API, eine bessere Unterstützung von Unicode und, was entscheidend ist, eine
Fehlererkennung. Jeder Fehler beim Kompilieren oder beim Verarbeiten des Ausdrucks wirft eine
Nette\RegexpException.
split (string $subject, string $pattern, bool $captureOffset=false, bool $skipEmpty=false, int $limit=-1, bool $utf8=false): array
Teilt einen String anhand eines regulären Ausdrucks in ein Array. Auch die Ausdrücke in Klammern werden erfasst und zurückgegeben.
Strings::split('hello, world', '~,\s*~');
// ['hello', 'world']
Strings::split('hello, world', '~(,)\s*~');
// ['hello', ',', 'world']
Ist $skipEmpty gleich true, werden nur nicht leere Elemente zurückgegeben:
Strings::split('hello, world, ', '~,\s*~');
// ['hello', 'world', '']
Strings::split('hello, world, ', '~,\s*~', skipEmpty: true);
// ['hello', 'world']
Ist $limit angegeben, werden nur Teilstrings bis zu diesem Limit zurückgegeben, und der Rest des Strings landet
im letzten Element. Ein Limit von –1 oder 0 bedeutet keine Begrenzung.
Strings::split('hello, world, third', '~,\s*~', limit: 2);
// ['hello', 'world, third']
Ist $utf8 gleich true, schaltet die Auswertung in den Unicode-Modus, ähnlich wie beim Modifikator
u.
Ist $captureOffset gleich true, wird zusätzlich die Position jedes Treffers im String zurückgegeben
(in Bytes; in Zeichen, wenn $utf8 gesetzt ist). Das ändert den Rückgabewert in ein Array, dessen Elemente jeweils
ein Paar aus dem gefundenen String und seiner Position sind.
Strings::split('žlutý, kůň', '~,\s*~', captureOffset: true);
// [['žlutý', 0], ['kůň', 9]]
Strings::split('žlutý, kůň', '~,\s*~', captureOffset: true, utf8: true);
// [['žlutý', 0], ['kůň', 7]] // die Positionen sind in Zeichen
match (string $subject, string $pattern, bool $captureOffset=false, int $offset=0, bool $unmatchedAsNull=false, bool $utf8=false): ?array
Sucht im String nach einem Teil, der dem regulären Ausdruck entspricht, und gibt ein Array mit dem gefundenen Ausdruck und den
einzelnen Teilausdrücken zurück, oder null, wenn nichts gefunden wird.
Strings::match('hello!', '~\w+(!+)~');
// ['hello!', '!']
Strings::match('hello!', '~X~');
// null
Ist $unmatchedAsNull gleich true, werden nicht getroffene Teilausdrücke als null
zurückgegeben, sonst als leerer String oder gar nicht:
Strings::match('hello', '~\w+(!+)?~');
// ['hello'] (die optionale Gruppe !+ hat nicht getroffen)
Strings::match('hello', '~\w+(!+)?~', unmatchedAsNull: true);
// ['hello', null]
Ist $utf8 gleich true, schaltet die Auswertung in den Unicode-Modus, ähnlich wie beim Modifikator
u:
Strings::match('žlutý kůň', '~\w+~'); // ohne UTF-8
// ['lut'] (trifft nur ASCII-Wortzeichen)
Strings::match('žlutý kůň', '~\w+~', utf8: true); // mit UTF-8
// ['žlutý'] (trifft Unicode-Wortzeichen)
Mit dem Parameter $offset lässt sich die Position angeben, ab der gesucht wird (in Bytes; in Zeichen, wenn
$utf8 gesetzt ist).
Ist $captureOffset gleich true, wird zusätzlich die Position jedes Treffers im String zurückgegeben
(in Bytes; in Zeichen, wenn $utf8 gesetzt ist). Das ändert den Rückgabewert in ein Array, dessen Elemente jeweils
ein Paar aus dem gefundenen String und seinem Offset sind:
Strings::match('žlutý!', '~\w+(!+)?~', captureOffset: true); // ohne UTF-8
// [['lut', 2]] (nur ASCII-Treffer, Offset in Bytes)
Strings::match('žlutý!', '~\w+(!+)?~', captureOffset: true, utf8: true); // mit UTF-8
// [['žlutý!', 0], ['!', 5]] (Unicode-Treffer, Offsets in Zeichen)
matchAll (string $subject, string $pattern, bool $captureOffset=false, int $offset=0, bool $unmatchedAsNull=false, bool $patternOrder=false, bool $utf8=false, bool $lazy=false): array|Generator
Sucht im String nach allen Vorkommen, die dem regulären Ausdruck entsprechen, und gibt ein Array von Arrays mit dem gefundenen Ausdruck und den einzelnen Teilausdrücken zurück.
Strings::matchAll('hello, world!!', '~\w+(!+)?~');
/* [
0 => ['hello'],
1 => ['world!!', '!!'],
] */
Ist $patternOrder gleich true, ändert sich die Struktur der Ergebnisse: Das erste Element ist ein
Array aller vollständigen Treffer, das zweite ein Array der Strings, die dem ersten geklammerten Teilausdruck entsprechen, und so
weiter:
Strings::matchAll('hello, world!!', '~\w+(!+)?~', patternOrder: true);
/* [
0 => ['hello', 'world!!'],
1 => ['', '!!'],
] */
Ist $unmatchedAsNull gleich true, werden nicht getroffene Teilausdrücke als null
zurückgegeben, sonst als leerer String oder gar nicht:
Strings::matchAll('hello, world!!', '~\w+(!+)?~', unmatchedAsNull: true);
/* [
0 => ['hello', null],
1 => ['world!!', '!!'],
] */
Ist $utf8 gleich true, schaltet die Auswertung in den Unicode-Modus, ähnlich wie beim Modifikator
u:
Strings::matchAll('žlutý kůň', '~\w+~');
/* [
0 => ['lut'],
1 => ['k'],
] */
Strings::matchAll('žlutý kůň', '~\w+~', utf8: true);
/* [
0 => ['žlutý'],
1 => ['kůň'],
] */
Mit dem Parameter $offset lässt sich die Position angeben, ab der gesucht wird (in Bytes; in Zeichen, wenn
$utf8 gesetzt ist).
Ist $captureOffset gleich true, wird zusätzlich die Position jedes Treffers im String zurückgegeben
(in Bytes; in Zeichen, wenn $utf8 gesetzt ist). Das ändert die Struktur des Rückgabewerts, wobei jedes
Trefferelement ein Paar [gefundener_String, Position] ist:
Strings::matchAll('žlutý kůň', '~\w+~', captureOffset: true);
/* [
0 => [['lut', 2]],
1 => [['k', 8]],
] */
Strings::matchAll('žlutý kůň', '~\w+~', captureOffset: true, utf8: true);
/* [
0 => [['žlutý', 0]],
1 => [['kůň', 6]],
] */
Ist $lazy gleich true, gibt die Funktion statt eines Arrays einen Generator zurück. Bei
der Arbeit mit großen Strings bringt das einen erheblichen Leistungsvorteil, weil die Treffer nach und nach gefunden werden,
statt den gesamten String auf einmal zu verarbeiten. So lassen sich auch extrem große Eingaben effizient verarbeiten. Außerdem
können Sie die Verarbeitung jederzeit abbrechen, sobald Sie den gesuchten Treffer gefunden haben, und sparen so Rechenzeit.
$matches = Strings::matchAll($largeText, '~\w+~', lazy: true);
foreach ($matches as $match) {
echo "Gefunden: $match[0]\n";
// Die Verarbeitung lässt sich jederzeit abbrechen, z. B. mit break;
}
replace (string $subject, string|array
$pattern, string|callable $replacement='', int $limit=-1, bool $captureOffset=false, bool
$unmatchedAsNull=false, bool $utf8=false): string
Ersetzt alle Vorkommen, die dem regulären Ausdruck entsprechen. $replacement ist entweder eine Maske für den
Ersatzstring oder eine Callback-Funktion.
Strings::replace('hello, world!', '~\w+~', '--');
// '--, --!'
Strings::replace('hello, world!', '~\w+~', fn($m) => strrev($m[0]));
// 'olleh, dlrow!'
Die Funktion erlaubt auch mehrere Ersetzungen auf einmal, indem als zweiter Parameter ein Array im Format
Muster => Ersatz übergeben wird:
Strings::replace('hello, world!', [
'~\w+~' => '--',
'~,\s+~' => ' ',
]);
// '-- --!'
Der Parameter $limit begrenzt die Anzahl der durchgeführten Ersetzungen. Ein Limit von –1 bedeutet keine
Begrenzung.
Ist $utf8 gleich true, schaltet die Auswertung in den Unicode-Modus, ähnlich wie beim Modifikator
u.
Strings::replace('žlutý kůň', '~\w+~', '--');
// 'ž--ý --ůň'
Strings::replace('žlutý kůň', '~\w+~', '--', utf8: true);
// '-- --'
Ist $captureOffset gleich true, wird dem Callback zusätzlich die Position jedes Treffers im String
übergeben (in Bytes; in Zeichen, wenn $utf8 gesetzt ist). Das ändert die Struktur des übergebenen Arrays, dessen
Elemente jeweils ein Paar [gefundener_String, Position] sind.
Strings::replace(
'žlutý kůň',
'~\w+~',
function (array $m) { dump($m); return ''; },
captureOffset: true,
);
// gibt [['lut', 2]] und [['k', 8]] aus
Strings::replace(
'žlutý kůň',
'~\w+~',
function (array $m) { dump($m); return ''; },
captureOffset: true,
utf8: true,
);
// gibt [['žlutý', 0]] und [['kůň', 6]] aus
Ist $unmatchedAsNull gleich true, werden nicht getroffene Teilausdrücke dem Callback als
null übergeben, sonst als leerer String oder gar nicht:
Strings::replace(
'ac',
'~(a)(b)*(c)~',
function (array $m) { dump($m); return ''; },
);
// gibt ['ac', 'a', '', 'c'] aus
Strings::replace(
'ac',
'~(a)(b)*(c)~',
function (array $m) { dump($m); return ''; },
unmatchedAsNull: true,
);
// gibt ['ac', 'a', null, 'c'] aus