From 6f87c49d4ec987cd855ea8587d780a628c5fe23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Sat, 3 Oct 2026 17:32:50 +0200 Subject: [PATCH] fix: Improve regex to extract unstructured fields --- Tests/Unit/CAMT/CAMTStructuredFieldsTest.php | 38 ++++++++++++++++++++ src/CAMT/CAMT.php | 19 +++++----- 2 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 Tests/Unit/CAMT/CAMTStructuredFieldsTest.php diff --git a/Tests/Unit/CAMT/CAMTStructuredFieldsTest.php b/Tests/Unit/CAMT/CAMTStructuredFieldsTest.php new file mode 100644 index 00000000..5b1fa506 --- /dev/null +++ b/Tests/Unit/CAMT/CAMTStructuredFieldsTest.php @@ -0,0 +1,38 @@ +extractReflectionMethod = new \ReflectionMethod(CAMT::class, 'extractStructuredFieldsFromText'); + $this->extractReflectionMethod->setAccessible(true); + } + + /** + * @dataProvider UstrdProvider + */ + public function testExtractStructuredFieldsFromText(string $text, array $expectedStructuredTags): void + { + $parser = new CAMT(); + + $fields = $this->extractReflectionMethod->invoke($parser, $text); + + self::assertSame($expectedStructuredTags, $fields); + } + + public static function UstrdProvider(): array + { + return [ + ['This is a plain textEREF+EEID-20260804-123MREF+123CRED+DE456', ['EREF' => 'EEID-20260804-123', 'MREF' => '123', 'CRED' => 'DE456']], + ['SVWZ+Payment for invoice 123EREF+ABC123 MREF+XYZ789', ['SVWZ' => 'Payment for invoice 123', 'EREF' => 'ABC123', 'MREF' => 'XYZ789']], + ['EREF+ABC123SVWZ+Payment for invoice 123IBAN+DE44500105175407324931', ['EREF' => 'ABC123', 'SVWZ' => 'Payment for invoice 123', 'IBAN' => 'DE44500105175407324931']], + ]; + } +} diff --git a/src/CAMT/CAMT.php b/src/CAMT/CAMT.php index 0ce06fd5..58790d0a 100644 --- a/src/CAMT/CAMT.php +++ b/src/CAMT/CAMT.php @@ -648,18 +648,17 @@ private function extractStructuredFieldsFromText(string $text): array // Common SEPA field patterns $patterns = [ - 'EREF' => '/EREF\+([^\s]+)/', - 'MREF' => '/MREF\+([^\s]+)/', - 'CRED' => '/CRED\+([^\s]+)/', - 'DEBT' => '/DEBT\+([^\s]+)/', - 'SVWZ' => '/SVWZ\+(.+?)(?=(?:EREF|MREF|CRED|DEBT|\s*$))/', - 'KREF' => '/KREF\+([^\s]+)/', - 'IBAN' => '/IBAN\+([A-Z]{2}[0-9]{2}[A-Z0-9]+)/', + '/(?EREF|MREF|CRED|DEBT|SVWZ|KREF)\+(?.*?)(?=(?:EREF|MREF|CRED|DEBT|SVWZ|KREF|IBAN|\s*$))/', + '/(?IBAN)\+(?[A-Z]{2}[0-9]{2}[A-Z0-9]+)/', ]; - foreach ($patterns as $key => $pattern) { - if (preg_match($pattern, $text, $matches)) { - $fields[$key] = trim($matches[1]); + foreach ($patterns as $pattern) { + if (preg_match_all($pattern, $text, $matches)) { + for ($i = 0; $i < count($matches['key']); ++$i) { + $key = $matches['key'][$i]; + $value = $matches['value'][$i]; + $fields[$key] = trim($value); + } } }