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']