splitIntoLines((string) $blob, $countryName); if ($lines === []) { return null; } // PLZ+Ort von hinten suchen — alles danach wurde bereits als // Länderzeile aussortiert. $postalIndex = null; $postalCode = null; $city = null; for ($i = count($lines) - 1; $i >= 0; $i--) { if (preg_match(self::POSTAL_CITY_PATTERN, $lines[$i], $matches) === 1) { $postalIndex = $i; $postalCode = $matches[1]; $city = trim($matches[2]); break; } } if ($postalIndex === null || $postalIndex === 0) { // Keine PLZ+Ort-Zeile oder nichts davor (keine Straße) → manuell. return null; } $before = array_slice($lines, 0, $postalIndex); $company = null; foreach ($before as $index => $line) { if (preg_match(self::COMPANY_PATTERN, $line) === 1) { $company = $line; unset($before[$index]); break; } } $before = array_values($before); if ($before === []) { return null; } // Straße = erste Zeile mit Hausnummer (Ziffer); Zusätze wie // "5th Floor" oder Ansprechpartner wandern nach address2. $address1 = null; foreach ($before as $index => $line) { if (preg_match('/\d/', $line) === 1) { $address1 = $line; unset($before[$index]); break; } } if ($address1 === null) { $address1 = array_shift($before); } $address2 = $before === [] ? null : implode(', ', $before); return [ 'company' => $company, 'address1' => $address1, 'address2' => $address2, 'postal_code' => $postalCode, 'city' => $city, ]; } /** * Blob in bereinigte Zeilen zerlegen: Zeilenumbrüche, bei einzeiligen * Blobs Kommata als Trenner; eine reine Länderzeile am Ende (z. B. * "Cyprus") wird entfernt. * * @return list */ private function splitIntoLines(string $blob, ?string $countryName): array { $lines = preg_split('/\R/u', trim($blob)) ?: []; $lines = array_values(array_filter(array_map(trim(...), $lines), fn (string $line): bool => $line !== '')); if (count($lines) === 1 && str_contains($lines[0], ',') && preg_match(self::POSTAL_CITY_PATTERN, $lines[0]) !== 1) { $lines = array_values(array_filter(array_map(trim(...), explode(',', $lines[0])), fn (string $line): bool => $line !== '')); } if ($countryName !== null && $lines !== [] && strcasecmp((string) end($lines), $countryName) === 0) { array_pop($lines); } return $lines; } }