How to remove duplicate case‑insensitive words separated by multiple delimiters from a string in PHP

1 Answer

0 votes
/*
    Remove duplicate case‑insensitive words separated by multiple delimiters.

    Features:
    - Case‑insensitive comparison (mb_strtolower)
    - Preserves original casing of the first occurrence
    - Trims whitespace around tokens
    - Supports ANY number of delimiters (including multi‑character)
    - Preserves original order
    - Efficient O(n) lookup using associative array as a hash set

    Algorithm:
    1. Build a regex that matches ANY delimiter.
    2. Split the string using preg_split.
    3. Trim each token.
    4. Convert to lowercase for comparison.
    5. Keep only first occurrence.
    6. Reassemble using a chosen delimiter.
*/

function removeDuplicatesMultiDelimiterCI(string $input, array $delimiters, string $outputDelimiter): string
{
    // Step 1: Build a regex that matches ANY delimiter
    // preg_quote ensures delimiters like "|" or "*" are treated literally
    $escaped = array_map('preg_quote', $delimiters);
    $pattern = '/(?:' . implode('|', $escaped) . ')+/u';

    // Step 2: Split by ANY delimiter sequence
    $tokens = preg_split($pattern, $input, -1, PREG_SPLIT_NO_EMPTY);

    // Step 3: Remove duplicates (case‑insensitive)
    $seen = [];
    $unique = [];

    foreach ($tokens as $token) {
        $trimmed = trim($token);
        if ($trimmed === '') {
            continue;
        }

        // Case‑insensitive key
        $key = mb_strtolower($trimmed, 'UTF-8');

        if (!isset($seen[$key])) {
            $seen[$key] = true;
            $unique[] = $trimmed;   // preserve original casing
        }
    }

    // Step 4: Reassemble
    return implode($outputDelimiter, $unique);
}

// Main
$s = "AAA | aaa ,   aAA * aaA | AAa | AAA   | BBB | ccc ---- CCC | AAA ; aaa | bbb";

// Multiple delimiters
$delimiters = ["  ", "|", ",", "*", "-", ";"];

$result = removeDuplicatesMultiDelimiterCI($s, $delimiters, " | ");

echo $result;



/*
run:

AAA | BBB | ccc

*/

 



answered Aug 1 by avibootz

Related questions

...