Lucrul cu șiruri de caractere

Nette\Utils\Strings este o clasă statică cu funcții utile pentru lucrul cu șiruri de caractere, în principal în codificarea UTF-8.

Instalare:

composer require nette/utils

Toate exemplele presupun crearea unui alias:

use Nette\Utils\Strings;

Modificarea majusculelor/minusculelor

Aceste funcții necesită extensia PHP mbstring.

lower (string $s): string

Convertește un șir UTF-8 în litere mici.

Strings::lower('Dobrý den'); // 'dobrý den'

upper (string $s): string

Convertește un șir UTF-8 în litere mari.

Strings::upper('Dobrý den'); // 'DOBRÝ DEN'

firstUpper (string $s): string

Convertește prima literă a unui șir UTF-8 în majusculă, restul rămânând neschimbate.

Strings::firstUpper('dobrý den'); // 'Dobrý den'

firstLower (string $s): string

Convertește prima literă a unui șir UTF-8 în minusculă, restul rămânând neschimbate.

Strings::firstLower('Dobrý den'); // 'dobrý den'

capitalize (string $s): string

Convertește prima literă a fiecărui cuvânt dintr-un șir UTF-8 în majusculă, restul în minuscule.

Strings::capitalize('Dobrý den'); // 'Dobrý Den'

Modificarea șirului

normalize (string $s): string

Elimină caracterele de control, normalizează sfârșiturile de linie la \n, elimină liniile goale de la început și sfârșit, elimină spațiile de la sfârșitul liniilor, normalizează UTF-8 la forma normală NFC.

unixNewLines (string $s): string

Convertește sfârșiturile de linie la \n utilizate în sistemele Unix. Sfârșiturile de linie sunt: \n, \r, \r\n, U+2028 separator de linie, U+2029 separator de paragraf.

$unixLikeLines = Strings::unixNewLines($string);

platformNewLines (string $s)string

Convertește sfârșiturile de linie la caracterele specifice platformei curente, adică \r\n pe Windows și \n în altă parte. Sfârșiturile de linie sunt: \n, \r, \r\n, U+2028 separator de linie, U+2029 separator de paragraf.

$platformLines = Strings::platformNewLines($string);

webalize (string $s, ?string $charlist=null, bool $lower=true)string

Modifică un șir UTF-8 în forma utilizată în URL-uri, adică elimină diacriticele și înlocuiește toate caracterele, cu excepția literelor alfabetului englez și a cifrelor, cu cratime.

Strings::webalize('náš produkt'); // 'nas-produkt'

Dacă trebuie păstrate și alte caractere, acestea pot fi specificate în al doilea parametru al funcției.

Strings::webalize('10. obrázek_id', '._'); // '10.-obrazek_id'

Cu al treilea parametru, conversia la litere mici poate fi suprimată.

Strings::webalize('Dobrý den', null, false); // 'Dobry-den'

Necesită extensia PHP intl.

trim (string $s, ?string $charlist=null)string

Elimină spațiile (sau alte caractere specificate de al doilea parametru) de la începutul și sfârșitul unui șir UTF-8.

Strings::trim('  Hello  '); // 'Hello'

truncate (string $s, int $maxLen, string $append=`'…'`)string

Trunchiază un șir UTF-8 la lungimea maximă specificată, încercând în același timp să păstreze cuvintele întregi. Dacă șirul este scurtat, adaugă puncte de suspensie la sfârșit (poate fi schimbat cu al treilea parametru).

$text = 'Řekněte, jak se máte?';
Strings::truncate($text, 5);       // 'Řekn…'
Strings::truncate($text, 20);      // 'Řekněte, jak se…'
Strings::truncate($text, 30);      // 'Řekněte, jak se máte?'
Strings::truncate($text, 20, '~'); // 'Řekněte, jak se~'

indent (string $s, int $level=1, string $indentationChar=`"\t"`)string

Indentează textul multi-linie de la stânga. Numărul de indentări este specificat de al doilea parametru, iar caracterul de indentare de al treilea parametru (valoarea implicită este tabulator).

Strings::indent('Nette');         // "\tNette"
Strings::indent('Nette', 2, '+'); // '++Nette'

padLeft (string $s, int $length, string $pad=`' '`)string

Completează un șir UTF-8 la lungimea specificată prin repetarea șirului $pad la stânga.

Strings::padLeft('Nette', 6);        // ' Nette'
Strings::padLeft('Nette', 8, '+*');  // '+*+Nette'

padRight (string $s, int $length, string $pad=`' '`)string

Completează un șir UTF-8 la lungimea specificată prin repetarea șirului $pad la dreapta.

Strings::padRight('Nette', 6);       // 'Nette '
Strings::padRight('Nette', 8, '+*'); // 'Nette+*+'

substring (string $s, int $start, ?int $length=null)string

Returnează o parte a șirului UTF-8 $s specificată de poziția de start $start și lungimea $length. Dacă $start este negativ, șirul returnat va începe cu al -$start`-lea caracter de la sfârșit.

Strings::substring('Nette Framework', 0, 5); // 'Nette'
Strings::substring('Nette Framework', 6);    // 'Framework'
Strings::substring('Nette Framework', -4);   // 'work'

reverse (string $s): string

Inversează un șir UTF-8.

Strings::reverse('Nette'); // 'etteN'

length (string $s): int

Returnează numărul de caractere (nu de octeți) dintr-un șir UTF-8.

Acesta este numărul de puncte de cod Unicode, care poate diferi de numărul de grafeme.

Strings::length('Nette');   // 5
Strings::length('červená'); // 7

startsWith (string $haystack, string $needle)bool

Verifică dacă șirul $haystack începe cu șirul $needle.

$haystack = 'Začíná';
$needle = 'Za';
Strings::startsWith($haystack, $needle); // true

Utilizați funcția nativă str_starts_with().

endsWith (string $haystack, string $needle)bool

Verifică dacă șirul $haystack se termină cu șirul $needle.

$haystack = 'Končí';
$needle = 'čí';
Strings::endsWith($haystack, $needle); // true

Utilizați funcția nativă str_ends_with().

contains (string $haystack, string $needle)bool

Verifică dacă șirul $haystack conține $needle.

$haystack = 'Posluchárna';
$needle = 'sluch';
Strings::contains($haystack, $needle); // true

Utilizați funcția nativă str_contains().

compare (string $left, string $right, ?int $length=null)bool

Compară două șiruri UTF-8 sau părți ale acestora, ignorând majusculele/minusculele. Dacă $length este null, se compară șirurile întregi; dacă este negativ, se compară numărul corespunzător de caractere de la sfârșitul șirurilor; altfel, se compară numărul corespunzător de caractere de la început.

Strings::compare('Nette', 'nette');     // true
Strings::compare('Nette', 'next', 2);   // true - potrivire primele 2 caractere
Strings::compare('Nette', 'Latte', -2); // true - potrivire ultimele 2 caractere

findPrefix (…$strings): string

Găsește prefixul comun al șirurilor. Sau returnează un șir gol dacă nu a fost găsit niciun prefix comun.

Strings::findPrefix('prefix-a', 'prefix-bb', 'prefix-c');   // 'prefix-'
Strings::findPrefix(['prefix-a', 'prefix-bb', 'prefix-c']); // 'prefix-'
Strings::findPrefix('Nette', 'is', 'great');                // ''

before (string $haystack, string $needle, int $nth=1): ?string

Returnează partea șirului $haystack dinaintea celei de-a $nth-a apariții a șirului $needle. Sau null dacă $needle nu a fost găsit. Cu o valoare negativă pentru $nth, căutarea se face de la sfârșitul șirului.

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

Returnează partea șirului $haystack de după a $nth-a apariție a șirului $needle. Sau null dacă $needle nu a fost găsit. Cu o valoare negativă pentru $nth, căutarea se face de la sfârșitul șirului.

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

Returnează poziția în caractere a celei de-a $nth-a apariții a șirului $needle în șirul $haystack. Sau null dacă $needle nu a fost găsit. Cu o valoare negativă pentru $nth, căutarea se face de la sfârșitul șirului.

Strings::indexOf('abc abc abc', 'abc', 2);  // 4
Strings::indexOf('abc abc abc', 'abc', -1); // 8
Strings::indexOf('abc abc abc', 'd');       // null

Codificare

fixEncoding (string $s): string

Elimină caracterele UTF-8 invalide din șir.

$correctStrings = Strings::fixEncoding($string);

checkEncoding (string $s)bool

Verifică dacă este un șir UTF-8 valid.

$isUtf8 = Strings::checkEncoding($string);

Utilizați Nette\Utils\Validator::isUnicode().

toAscii (string $s): string

Convertește un șir UTF-8 în ASCII, adică elimină diacriticele etc.

Strings::toAscii('žluťoučký kůň'); // 'zlutoucky kun'

Necesită extensia PHP intl.

chr (int $code): string

Returnează un caracter specific în UTF-8 dintr-un punct de cod (număr în intervalul 0×0000..D7FF și 0xE000..10FFFF).

Strings::chr(0xA9); // '©' în codificare UTF-8

ord (string $char): int

Returnează punctul de cod al unui caracter specific în UTF-8 (număr în intervalul 0×0000..D7FF sau 0xE000..10FFFF).

Strings::ord('©'); // 0xA9

Expresii regulate

Clasa Strings oferă funcții pentru lucrul cu expresii regulate. Spre deosebire de funcțiile native PHP, acestea au un API mai inteligibil, suport Unicode mai bun și, mai presus de toate, detectarea erorilor. Orice eroare la compilarea sau procesarea expresiei aruncă o excepție Nette\RegexpException.

split (string $subject, string $pattern, bool $captureOffset=false, bool $skipEmpty=false, int $limit=-1, bool $utf8=false)array

Împarte un șir într-un array conform unei expresii regulate. Expresiile din paranteze vor fi, de asemenea, capturate și returnate.

Strings::split('hello, world', '~,\s*~');
// ['hello', 'world']

Strings::split('hello, world', '~(,)\s*~');
// ['hello', ',', 'world']``

Dacă $skipEmpty este true, vor fi returnate doar elementele ne-goale:

Strings::split('hello, world, ', '~,\s*~');
// ['hello', 'world', '']

Strings::split('hello, world, ', '~,\s*~', skipEmpty: true);
// ['hello', 'world']

Dacă este specificat $limit, vor fi returnate doar subșirurile până la limită, iar restul șirului va fi plasat în ultimul element. O limită de –1 sau 0 înseamnă nicio restricție.

Strings::split('hello, world, third', '~,\s*~', limit: 2);
// ['hello', 'world, third']

Dacă $utf8 este true, evaluarea trece în modul Unicode. Similar cu specificarea modificatorului u.

Dacă $captureOffset este true, pentru fiecare potrivire găsită va fi returnată și poziția sa în șir (în octeți; dacă $utf8 este setat, atunci în caractere). Acest lucru schimbă valoarea returnată într-un array în care fiecare element este o pereche formată din șirul potrivit și poziția sa.

Strings::split('žlutý, kůň', '~,\s*~', captureOffset: true);
// [['žlutý', 0], ['kůň', 9]]

Strings::split('žlutý, kůň', '~,\s*~', captureOffset: true, utf8: true);
// [['žlutý', 0], ['kůň', 7]]

match (string $subject, string $pattern, bool $captureOffset=false, int $offset=0, bool $unmatchedAsNull=false, bool $utf8=false)?array

Caută în șir o parte care corespunde expresiei regulate și returnează un array cu expresia găsită și subexpresiile individuale, sau null.

Strings::match('hello!', '~\w+(!+)~');
// ['hello!', '!']

Strings::match('hello!', '~X~');
// null

Dacă $unmatchedAsNull este true, submodelele necapturate sunt returnate ca null; altfel, sunt returnate ca șir gol sau nu sunt returnate:

Strings::match('hello', '~\w+(!+)?~');
// ['hello']

Strings::match('hello', '~\w+(!+)?~', unmatchedAsNull: true);
// ['hello', null]

Dacă $utf8 este true, evaluarea trece în modul Unicode. Similar cu specificarea modificatorului u:

Strings::match('žlutý kůň', '~\w+~');
// ['lut']

Strings::match('žlutý kůň', '~\w+~', utf8: true);
// ['žlutý']

Parametrul $offset poate fi utilizat pentru a specifica poziția de la care să înceapă căutarea (în octeți; dacă $utf8 este setat, atunci în caractere).

Dacă $captureOffset este true, pentru fiecare potrivire găsită va fi returnată și poziția sa în șir (în octeți; dacă $utf8 este setat, atunci în caractere). Acest lucru schimbă valoarea returnată într-un array în care fiecare element este o pereche formată din șirul potrivit și offset-ul său:

Strings::match('žlutý!', '~\w+(!+)?~', captureOffset: true);
// [['lut', 2]]

Strings::match('žlutý!', '~\w+(!+)?~', captureOffset: true, utf8: true);
// [['žlutý!', 0], ['!', 5]]

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

Caută în șir toate aparițiile care corespund expresiei regulate și returnează un array de array-uri cu expresia găsită și subexpresiile individuale.

Strings::matchAll('hello, world!!', '~\w+(!+)?~');
/* [
	0 => ['hello'],
	1 => ['world!!', '!!'],
] */

Dacă $patternOrder este true, structura rezultatelor se schimbă astfel încât primul element este un array de potriviri complete ale modelului, al doilea este un array de șiruri care corespund primului submodel din paranteze, și așa mai departe:

Strings::matchAll('hello, world!!', '~\w+(!+)?~', patternOrder: true);
/* [
	0 => ['hello', 'world!!'],
	1 => ['', '!!'],
] */

Dacă $unmatchedAsNull este true, submodelele necapturate sunt returnate ca null; altfel, sunt returnate ca șir gol sau nu sunt returnate:

Strings::matchAll('hello, world!!', '~\w+(!+)?~', unmatchedAsNull: true);
/* [
	0 => ['hello', null],
	1 => ['world!!', '!!'],
] */

Dacă $utf8 este true, evaluarea trece în modul Unicode. Similar cu specificarea modificatorului u:

Strings::matchAll('žlutý kůň', '~\w+~');
/* [
	0 => ['lut'],
	1 => ['k'],
] */

Strings::matchAll('žlutý kůň', '~\w+~', utf8: true);
/* [
	0 => ['žlutý'],
	1 => ['kůň'],
] */

Parametrul $offset poate fi utilizat pentru a specifica poziția de la care să înceapă căutarea (în octeți; dacă $utf8 este setat, atunci în caractere).

Dacă $captureOffset este true, pentru fiecare potrivire găsită va fi returnată și poziția sa în șir (în octeți; dacă $utf8 este setat, atunci în caractere). Acest lucru schimbă valoarea returnată într-un array în care fiecare element este o pereche formată din șirul potrivit și poziția sa:

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]],
] */

Dacă $lazy este true, funcția returnează un Generator în loc de un array, ceea ce aduce avantaje semnificative de performanță la lucrul cu șiruri mari. Generatorul permite căutarea potrivirilor treptat, în loc de întregul șir deodată. Acest lucru permite lucrul eficient chiar și cu texte de intrare extrem de mari. În plus, puteți întrerupe procesarea oricând dacă găsiți potrivirea căutată, economisind timp de calcul.

$matches = Strings::matchAll($largeText, '~\w+~', lazy: true);
foreach ($matches as $match) {
    echo "Găsit: $match[0]\n";
    // Procesarea poate fi întreruptă oricând
}

replace (string $subject, string|array $pattern, string|callable $replacement='', int $limit=-1, bool $captureOffset=false, bool $unmatchedAsNull=false, bool $utf8=false)string

Înlocuiește toate aparițiile care corespund expresiei regulate. $replacement este fie o mască de șir de înlocuire, fie un callback.

Strings::replace('hello, world!', '~\w+~', '--');
// '--, --!'

Strings::replace('hello, world!', '~\w+~', fn($m) => strrev($m[0]));
// 'olleh, dlrow!'

Funcția permite, de asemenea, efectuarea mai multor înlocuiri prin transmiterea unui array în al doilea parametru sub forma pattern => replacement:

Strings::replace('hello, world!', [
	'~\w+~' => '--',
	'~,\s+~' => ' ',
]);
// '-- --!'

Parametrul $limit limitează numărul de înlocuiri efectuate. O limită de –1 înseamnă nicio restricție.

Dacă $utf8 este true, evaluarea trece în modul Unicode. Similar cu specificarea modificatorului u.

Strings::replace('žlutý kůň', '~\w+~', '--');
// 'ž--ý --ůň'

Strings::replace('žlutý kůň', '~\w+~', '--', utf8: true);
// '-- --'

Dacă $captureOffset este true, pentru fiecare potrivire găsită va fi transmisă callback-ului și poziția sa în șir (în octeți; dacă $utf8 este setat, atunci în caractere). Acest lucru schimbă forma array-ului transmis, unde fiecare element este o pereche formată din șirul potrivit și poziția sa.

Strings::replace(
	'žlutý kůň',
	'~\w+~',
	function (array $m) { dump($m); return ''; },
	captureOffset: true,
);
// dumps [['lut', 2]] și [['k', 8]]

Strings::replace(
	'žlutý kůň',
	'~\w+~',
	function (array $m) { dump($m); return ''; },
	captureOffset: true,
	utf8: true,
);
// dumps [['žlutý', 0]] și [['kůň', 6]]

Dacă $unmatchedAsNull este true, submodelele necapturate sunt transmise callback-ului ca null; altfel, sunt transmise ca șir gol sau nu sunt transmise:

Strings::replace(
	'ac',
	'~(a)(b)*(c)~',
	function (array $m) { dump($m); return ''; },
);
// dumps ['ac', 'a', '', 'c']

Strings::replace(
	'ac',
	'~(a)(b)*(c)~',
	function (array $m) { dump($m); return ''; },
	unmatchedAsNull: true,
);
// dumps ['ac', 'a', null, 'c']
versiune: 4.0