public function concordancePositions(string $text, string $needle, int $contextLength = 20, bool $ignorecase = true, string $position = 'contain') : array
    {
        $found = [];
        $needleLength = strlen($needle);
        $textLength = strlen($text);
        $bufferLength = $needleLength + 2 * $contextLength;

        // \p{L} or \p{Letter}: any kind of letter from any language.

        $special_chars = "\/\-_\'";
        $word_part = '\p{L}'.$special_chars;

        switch ($position) {
            case 'equal':
                $pattern = "/(?<![$word_part])($needle)(?![$word_part])/";
                break;
            case 'begin':
                $pattern = "/(?<![$word_part])($needle)[$special_chars]?[\p{L}]*|^($needle)/";
                break;
            case 'end':
                $pattern = "/[\p{L}]*[$special_chars]?[\p{L}]*($needle)(?![$word_part])/";
                break;
            case 'contain':
                $pattern = "/($needle)/";
                break;
            default:
                $pattern = "/($needle)/";
                break;
        }

        $case = $ignorecase ? 'i' : '';
        preg_match_all($pattern.$case, $text, $matches, PREG_OFFSET_CAPTURE);
        $positions = array_column($matches[1], 1);

        return $positions;
    }