59 public function mask($text)
65 $text = preg_replace_callback(
66 '/\b(?=[A-Z0-9]*[0-9])(?=[A-Z0-9]*[A-Z])[A-Z0-9-_]{4,}\b/i',
79 $text = preg_replace_callback(
80 '/\b(?:\d[ -]*?){13,19}\b/',
81 [$this,
'maskCreditCardCallback'],
86 $text = preg_replace_callback(
87 '/\b[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{4,30}\b/',
99 $text = preg_replace_callback(
100 '/\b[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?\b/',
105 function (array $m) {
113 $text = preg_replace_callback(
114 '/(?i)(?:account\s+num(?:ber)?|bank\s+acct|acct\s*#)[:\s#]*\b(\d{8,17})\b/',
119 function (array $m) {
126 $text = preg_replace_callback(
127 '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/',
132 function (array $m) {
141 'name' =>
'EU VAT Numbers',
142 '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',
146 'name' =>
'Canadian GST/HST Numbers',
147 'regex' =>
'/\b\d{9}\s*RT\s*\d{4}\b/i',
151 'name' =>
'Australian ABN (Australian Business Number)',
152 'regex' =>
'/\b\d{2}\s*\d{3}\s*\d{3}\s*\d{3}\b/',
156 'name' =>
'Norwegian MVA (VAT) Numbers',
157 'regex' =>
'/\b\d{9}\s*MVA\b/i',
161 'name' =>
'Swiss VAT Numbers (MWST/TVA/IVA)',
162 'regex' =>
'/\bCHE-?\d{3}\.?\d{3}\.?\d{3}\s*(MWST|TVA|IVA)\b/i',
167 foreach ($taxPatterns as $pattern) {
168 $text = preg_replace_callback(
174 function (array $m) use ($pattern) {
175 return $this->
createToken($m[0], $pattern[
'token']);
184 'name' =>
'Greek International Numbers',
189 'regex' =>
'/(?<![\w+])(?:\+30|0030)[\s.\-]?(?:2\d|69)(?:[\s.\-()]?\d){8}(?!\d)/',
193 'name' =>
'Generic International Numbers',
198 'regex' =>
'/(?<![\w+])(?:\+|00)\d{1,3}(?:[\s.\-()]?\d){8,13}(?!\d)/',
202 'name' =>
'Greek National Numbers',
213 'regex' =>
'/(?<!\d)(?:2\d|69)(?:[\s.\-()]?\d){8}(?!\d)/',
217 'name' =>
'French National Numbers',
221 'regex' =>
'/\b0[1-9](?:[\s.-]?\d){8}\b/',
226 foreach ($phonePatterns as $pattern) {
227 $text = preg_replace_callback(
233 function (array $m) use ($pattern) {
234 return $this->
createToken($m[0], $pattern[
'token']);
247 $hardcoded_excludes = [
354 $dynamic_excludes = [];
355 if (is_object($langs)) {
356 for ($i = 1; $i <= 12; $i++) {
357 $key = sprintf(
"%02d", $i);
358 $dynamic_excludes[] = $langs->trans(
'Month' . $key);
359 $dynamic_excludes[] = $langs->trans(
'MonthShort' . $key);
365 $all_excludes_array = array_unique(array_merge($hardcoded_excludes, $dynamic_excludes));
368 $all_excludes_array = array_filter($all_excludes_array);
372 $excluded_words_regex = implode(
'|', array_map(
373 function (
string $word):
string {
374 return preg_quote($word,
'/');
381 $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';
387 'name' =>
'Number First (e.g., 123 Main St)',
389 'regex' =>
'/\b\d{1,5}\s+(?:[\p{L}\p{N}\.\'\-]+\s+){1,6}(?:' . $address_keywords .
')\b/ui',
393 'name' =>
'Keyword First (e.g., Rue de la Paix 12)',
395 'regex' =>
'/\b(?:' . $address_keywords .
')\s+(?:[\p{L}\p{N}\.\'\-]+\s+){1,6}\d{1,5}\b/ui',
399 'name' =>
'Name First, Keyword Middle (e.g., Main St 12)',
401 'regex' =>
'/\b(?:[\p{L}\p{N}\.\'\-]+\s+){1,4}(?:' . $address_keywords .
')\s+\d{1,5}\b/ui',
405 'name' =>
'Name First, No Keyword (Strict)',
411 'regex' =>
'/\b(?!(?:' . $excluded_words_regex .
')\b)\p{Lu}[\p{L}\p{N}\.\'\-]+\s+\d{1,5}\b/u',
416 foreach ($addressPatterns as $pattern) {
418 $text = preg_replace_callback(
424 function (array $m) use ($pattern) {
425 return $this->
createToken($m[0], $pattern[
'token']);
434 'name' =>
'UK Postal Codes',
436 'regex' =>
'/\b[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}\b/i',
440 'name' =>
'Canadian Postal Codes',
442 'regex' =>
'/\b[A-CEGHJ-NPR-STV-Z]\d[A-CEGHJ-NPR-STV-Z][ -]?\d[A-CEGHJ-NPR-STV-Z]\d\b/i',
446 'name' =>
'French Postal Codes',
449 'regex' =>
'/\b(0[1-9]\d{3}|[1-8]\d{4}|9[0-5]\d{2}|2[AB]\d{3})\b/',
453 'name' =>
'Greek Postal Codes',
456 'regex' =>
'/\b\d{3}\s?\d{2}\b/',
460 'name' =>
'US ZIP Codes',
462 'regex' =>
'/\b\d{5}(?:-\d{4})?\b/',
467 foreach ($zipCodePatterns as $pattern) {
468 $text = preg_replace_callback(
474 function (array $m) use ($pattern) {
475 return $this->
createToken($m[0], $pattern[
'token']);
571 if (empty($this->map)) {
576 $text = $this->
unmask($text);
580 foreach ($this->map as $fullToken => $originalValue) {
583 $strippedToken = substr($fullToken, 2, -2);
585 if (strpos($text, $strippedToken) !==
false) {
587 $text = str_replace($strippedToken, $originalValue, $text);