nur-sery/src/txt.php

295 lines
9.7 KiB
PHP

<?php
namespace nur\sery;
/**
* Class str: gestion des chaines de caractère multi-octets
*/
class txt {
/**
* Retourner $s converti en chaine non nulle, ou "" si $s est fausse (cela
* n'inclue pas la chaine "0")
*/
static final function with($s): string {
if (!is_string($s)) {
if (!$s) return "";
else $s = strval($s);
}
return $s;
}
/**
* Retourner $s converti en chaine non nulle, ou "" si $s est fausse selon les
* règles de PHP
*/
static final function pwith($s): string {
if (!is_string($s)) {
if (!$s) return "";
else $s = strval($s);
}
return $s?: "";
}
/**
* tronquer si nécessaire $s à la valeur $length.
* la chaine $suffix est rajoutée le cas échéant de façon que la taille
* totale n'excède pas $length caractères.
*
* si $ellips est true et que le troncage est nécessaire, remplacer les 3
* derniers caractères par "..."
*/
static final function trunc(?string $s, int $length, bool $ellips=false, ?string $suffix=null): ?string {
if ($s === null) return null;
if ($suffix !== null) $length -= mb_strlen($suffix);
if (mb_strlen($s) > $length) {
if ($ellips && $length > 3) $s = mb_substr($s, 0, $length - 3)."...";
else $s = mb_substr($s, 0, $length);
}
if ($suffix !== null) $s .= $suffix;
return $s;
}
/** trimmer $s */
static final function trim(?string $s): ?string {
if ($s === null) return null;
return trim($s);
}
/** trimmer $s à gauche */
static final function ltrim(?string $s): ?string {
if ($s === null) return null;
return ltrim($s);
}
/** trimmer $s à droite */
static final function rtrim(?string $s): ?string {
if ($s === null) return null;
return rtrim($s);
}
static final function left(?string $s, int $size): ?string {
if ($s === null) return null;
return mb_str_pad($s, $size);
}
static final function right(?string $s, int $size): ?string {
if ($s === null) return null;
return mb_str_pad($s, $size, " ", STR_PAD_LEFT);
}
static final function center(?string $s, int $size): ?string {
if ($s === null) return null;
return mb_str_pad($s, $size, " ", STR_PAD_BOTH);
}
static final function pad0(?string $s, int $size): ?string {
if ($s === null) return null;
return mb_str_pad($s, $size, "0", STR_PAD_LEFT);
}
static final function lower(?string $s): ?string {
if ($s === null) return null;
return mb_strtolower($s);
}
static final function lower1(?string $s): ?string {
if ($s === null) return null;
return mb_strtolower(mb_substr($s, 0, 1)).mb_substr($s, 1);
}
static final function upper(?string $s): ?string {
if ($s === null) return null;
return mb_strtoupper($s);
}
static final function upper1(?string $s): ?string {
if ($s === null) return null;
return mb_strtoupper(mb_substr($s, 0, 1)).mb_substr($s, 1);
}
static final function upperw(?string $s, ?string $delimiters=null): ?string {
if ($s === null) return null;
if ($delimiters === null) $delimiters = " _-\t\r\n\f\v";
$pattern = "/([".preg_quote($delimiters)."])/u";
$words = preg_split($pattern, $s, -1, PREG_SPLIT_DELIM_CAPTURE);
$max = count($words) - 1;
$ucwords = [];
for ($i = 0; $i < $max; $i += 2) {
$s = $words[$i];
$ucwords[] = mb_strtoupper(mb_substr($s, 0, 1)).mb_substr($s, 1);
$ucwords[] = $words[$i + 1];
}
$s = $words[$max];
$ucwords[] = mb_strtoupper(mb_substr($s, 0, 1)).mb_substr($s, 1);
return implode("", $ucwords);
}
protected static final function _starts_with(string $prefix, string $s, ?int $min_len=null): bool {
if ($prefix === $s) return true;
$len = mb_strlen($prefix);
if ($min_len !== null && ($len < $min_len || $len > mb_strlen($s))) return false;
return $len == 0 || $prefix === mb_substr($s, 0, $len);
}
/**
* tester si $s commence par $prefix
* par exemple:
* - starts_with("", "whatever") est true
* - starts_with("fi", "first") est true
* - starts_with("no", "yes") est false
*
* si $min_len n'est pas null, c'est la longueur minimum requise de $prefix
* pour qu'on teste la correspondance. dans le cas contraire, la valeur de
* retour est toujours false, sauf s'il y a égalité. e.g
* - starts_with("a", "abc", 2) est false
* - starts_with("a", "a", 2) est true
*/
static final function starts_with(?string $prefix, ?string $s, ?int $min_len=null): bool {
if ($s === null || $prefix === null) return false;
else return self::_starts_with($prefix, $s, $min_len);
}
/** Retourner $s sans le préfixe $prefix s'il existe */
static final function without_prefix(?string $prefix, ?string $s): ?string {
if ($s === null || $prefix === null) return $s;
if (self::_starts_with($prefix, $s)) $s = mb_substr($s, mb_strlen($prefix));
return $s;
}
/**
* modifier $s en place pour supprimer le préfixe $prefix s'il existe
*
* retourner true si le préfixe a été enlevé.
*/
static final function del_prefix(?string &$s, ?string $prefix): bool {
if ($s === null || !self::_starts_with($prefix, $s)) return false;
$s = self::without_prefix($prefix, $s);
return true;
}
/**
* Retourner $s avec le préfixe $prefix
*
* Si $unless_exists, ne pas ajouter le préfixe s'il existe déjà
*/
static final function with_prefix(?string $prefix, ?string $s, ?string $sep=null, bool $unless_exists=false): ?string {
if ($s === null || $prefix === null) return $s;
if (!self::_starts_with($prefix, $s) || !$unless_exists) $s = $prefix.$sep.$s;
return $s;
}
/**
* modifier $s en place pour ajouter le préfixe $prefix
*
* retourner true si le préfixe a été ajouté.
*/
static final function add_prefix(?string &$s, ?string $prefix, bool $unless_exists=true): bool {
if (($s === null || self::_starts_with($prefix, $s)) && $unless_exists) return false;
$s = self::with_prefix($prefix, $s, null, $unless_exists);
return true;
}
protected static final function _ends_with(string $suffix, string $s, ?int $min_len=null): bool {
if ($suffix === $s) return true;
$len = mb_strlen($suffix);
if ($min_len !== null && ($len < $min_len || $len > mb_strlen($s))) return false;
return $len == 0 || $suffix === mb_substr($s, -$len);
}
/**
* tester si $string se termine par $suffix
* par exemple:
* - ends_with("", "whatever") est true
* - ends_with("st", "first") est true
* - ends_with("no", "yes") est false
*
* si $min_len n'est pas null, c'est la longueur minimum requise de $prefix
* pour qu'on teste la correspondance. dans le cas contraire, la valeur de
* retour est toujours false, sauf s'il y a égalité. e.g
* - ends_with("c", "abc", 2) est false
* - ends_with("c", "c", 2) est true
*/
static final function ends_with(?string $suffix, ?string $s, ?int $min_len=null): bool {
if ($s === null || $suffix === null) return false;
else return self::_ends_with($suffix, $s, $min_len);
}
/** Retourner $s sans le suffixe $suffix s'il existe */
static final function without_suffix(?string $suffix, ?string $s): ?string {
if ($s === null || $suffix === null) return $s;
if (self::_ends_with($suffix, $s)) $s = mb_substr($s, 0, -mb_strlen($suffix));
return $s;
}
/**
* modifier $s en place pour supprimer le suffixe $suffix s'il existe
*
* retourner true si le suffixe a été enlevé.
*/
static final function del_suffix(?string &$s, ?string $suffix): bool {
if ($s === null || !self::_ends_with($suffix, $s)) return false;
$s = self::without_suffix($suffix, $s);
return true;
}
/**
* Retourner $s avec le suffixe $suffix
*
* Si $unless_exists, ne pas ajouter le suffixe s'il existe déjà
*/
static final function with_suffix(?string $suffix, ?string $s, ?string $sep=null, bool $unless_exists=false): ?string {
if ($s === null || $suffix === null) return $s;
if (!self::_ends_with($suffix, $s) || !$unless_exists) $s = $s.$sep.$suffix;
return $s;
}
/**
* modifier $s en place pour ajouter le suffixe $suffix
*
* retourner true si le suffixe a été ajouté.
*/
static final function add_suffix(?string &$s, ?string $suffix, bool $unless_exists=true): bool {
if (($s === null || self::_ends_with($suffix, $s)) && $unless_exists) return false;
$s = self::with_suffix($suffix, $s, null, $unless_exists);
return true;
}
/**
* ajouter $sep$prefix$text$suffix à $s si $text est non vide
*
* NB: ne rajouter $sep que si $s est non vide
*/
static final function addsep(?string &$s, ?string $sep, ?string $text, ?string $prefix=null, ?string $suffix=null): void {
if (!$text) return;
if ($s) $s .= $sep;
$s .= $prefix.$text.$suffix;
}
/** si $text est non vide, ajouter $prefix$text$suffix à $s en séparant la valeur avec un espace */
static final function add(?string &$s, ?string $text, ?string $prefix=null, ?string $suffix=null): void {
self::addsep($s, " ", $text, $prefix, $suffix);
}
#############################################################################
# divers
/**
* supprimer les diacritiques de la chaine $text
*
* la translitération se fait avec les règles de la locale spécifiée.
* NB: la translitération ne fonctionne pas si LC_CTYPE == C ou POISX
*/
static final function remove_diacritics(?string $text, string $locale="fr_FR.UTF-8"): ?string {
if ($text === null) return null;
#XXX est-ce thread-safe?
$olocale = setlocale(LC_CTYPE, 0);
try {
setlocale(LC_CTYPE, $locale);
$clean = @iconv("UTF-8", "US-ASCII//TRANSLIT", $text);
if ($clean === false) $clean = "";
return $clean;
} finally {
setlocale(LC_CTYPE, $olocale);
}
}
}