53 public function mask($text)
60 $text = preg_replace_callback(
61 '/\b(?=[A-Z0-9]*[0-9])(?=[A-Z0-9]*[A-Z])[A-Z0-9-_]{4,}\b/i',
74 $text = preg_replace_callback(
75 '/\b(?:\d[ -]*?){13,19}\b/',
76 [$this,
'maskCreditCardCallback'],
81 $text = preg_replace_callback(
82 '/\b[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{4,30}\b/',
94 $text = preg_replace_callback(
95 '/\b[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?\b/',
100 function (array $m) {
108 $text = preg_replace_callback(
109 '/(?i)(?:account\s+num(?:ber)?|bank\s+acct|acct\s*#)[:\s#]*\b(\d{8,17})\b/',
114 function (array $m) {
121 $text = preg_replace_callback(
122 '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/',
127 function (array $m) {
136 'name' =>
'EU VAT Numbers',
137 'regex' =>
'/\b(AT|BE|BG|CY|CZ|DE|DK|EE|EL|ES|FI|FR|GB|GR|HR|HU|IE|IT|LT|LU|LV|MT|NL|PL|PT|RO|SE|SI|SK)(?![a-z])[0-9A-Z]{2,12}\b/i',
141 'name' =>
'Canadian GST/HST Numbers',
142 'regex' =>
'/\b\d{9}\s*RT\s*\d{4}\b/i',
146 'name' =>
'Australian ABN (Australian Business Number)',
147 'regex' =>
'/\b\d{2}\s*\d{3}\s*\d{3}\s*\d{3}\b/',
151 'name' =>
'Norwegian MVA (VAT) Numbers',
152 'regex' =>
'/\b\d{9}\s*MVA\b/i',
156 'name' =>
'Swiss VAT Numbers (MWST/TVA/IVA)',
157 'regex' =>
'/\bCHE-?\d{3}\.?\d{3}\.?\d{3}\s*(MWST|TVA|IVA)\b/i',
162 foreach ($taxPatterns as $pattern) {
163 $text = preg_replace_callback(
169 function (array $m) use ($pattern) {
170 return $this->
createToken($m[0], $pattern[
'token']);
179 'name' =>
'Generic International Numbers',
180 'regex' =>
'/\b(?:\+|00)[0-9][0-9-.\s()]{8,}\b/',
184 'name' =>
'Greek National Numbers',
189 'regex' =>
'/\b(?:2[0-9-.\s()]{9}|69[0-9-.\s()]{8})\b/',
193 'name' =>
'French National Numbers',
197 'regex' =>
'/\b0[1-9](?:[\s.-]?\d){8}\b/',
202 foreach ($phonePatterns as $pattern) {
203 $text = preg_replace_callback(
209 function (array $m) use ($pattern) {
210 return $this->
createToken($m[0], $pattern[
'token']);
223 $hardcoded_excludes = [
330 $dynamic_excludes = [];
331 if (is_object($langs)) {
332 for ($i = 1; $i <= 12; $i++) {
333 $key = sprintf(
"%02d", $i);
334 $dynamic_excludes[] = $langs->trans(
'Month' . $key);
335 $dynamic_excludes[] = $langs->trans(
'MonthShort' . $key);
341 $all_excludes_array = array_unique(array_merge($hardcoded_excludes, $dynamic_excludes));
344 $all_excludes_array = array_filter($all_excludes_array);
348 $excluded_words_regex = implode(
'|', array_map(
349 function (
string $word):
string {
350 return preg_quote($word,
'/');
357 $address_keywords =
'Street|St|Road|Rd|Avenue|Ave|Lane|Ln|Boulevard|Blvd|Rue|Via|Strasse|Platz|Drive|Dr|Court|Ct|Way|Plaza|Square|Sq|Οδός|Λεωφόρος|Διεύθυνση|Piazza|Avenida';
363 'name' =>
'Number First (e.g., 123 Main St)',
365 'regex' =>
'/\b\d{1,5}\s+(?:[\p{L}\p{N}\.\'\-]+\s+){1,6}(?:' . $address_keywords .
')\b/ui',
369 'name' =>
'Keyword First (e.g., Rue de la Paix 12)',
371 'regex' =>
'/\b(?:' . $address_keywords .
')\s+(?:[\p{L}\p{N}\.\'\-]+\s+){1,6}\d{1,5}\b/ui',
375 'name' =>
'Name First, Keyword Middle (e.g., Main St 12)',
377 'regex' =>
'/\b(?:[\p{L}\p{N}\.\'\-]+\s+){1,4}(?:' . $address_keywords .
')\s+\d{1,5}\b/ui',
381 'name' =>
'Name First, No Keyword (Strict)',
387 'regex' =>
'/\b(?!(?:' . $excluded_words_regex .
')\b)\p{Lu}[\p{L}\p{N}\.\'\-]+\s+\d{1,5}\b/u',
392 foreach ($addressPatterns as $pattern) {
394 $text = preg_replace_callback(
400 function (array $m) use ($pattern) {
401 return $this->
createToken($m[0], $pattern[
'token']);
410 'name' =>
'UK Postal Codes',
412 'regex' =>
'/\b[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}\b/i',
416 'name' =>
'Canadian Postal Codes',
418 'regex' =>
'/\b[A-CEGHJ-NPR-STV-Z]\d[A-CEGHJ-NPR-STV-Z][ -]?\d[A-CEGHJ-NPR-STV-Z]\d\b/i',
422 'name' =>
'French Postal Codes',
425 'regex' =>
'/\b(0[1-9]\d{3}|[1-8]\d{4}|9[0-5]\d{2}|2[AB]\d{3})\b/',
429 'name' =>
'Greek Postal Codes',
432 'regex' =>
'/\b\d{3}\s?\d{2}\b/',
436 'name' =>
'US ZIP Codes',
438 'regex' =>
'/\b\d{5}(?:-\d{4})?\b/',
443 foreach ($zipCodePatterns as $pattern) {
444 $text = preg_replace_callback(
450 function (array $m) use ($pattern) {
451 return $this->
createToken($m[0], $pattern[
'token']);
547 if (empty($this->map)) {
552 $text = $this->
unmask($text);
556 foreach ($this->map as $fullToken => $originalValue) {
559 $strippedToken = substr($fullToken, 2, -2);
561 if (strpos($text, $strippedToken) !==
false) {
563 $text = str_replace($strippedToken, $originalValue, $text);