public function keyValueFromString($text)
    {
        // Match colon separator outside of quoted substrings
        // Fallback to nearest semicolon outside of quoted substrings, if colon cannot be found
        // Do not try and match within the value paired with the keyword
        preg_match('/(.*?)(?::(?=(?:[^"]*"[^"]*")*[^"]*$)|;(?=[^:]*$))([\w\W]*)/', htmlspecialchars($text, ENT_QUOTES, 'UTF-8'), $matches);

        if (count($matches) == 0) {
            return false;
        }

        if (preg_match('/^([A-Z-]+)([;][\w\W]*)?$/', $matches[1])) {
            $matches = array_splice($matches, 1, 2); // Remove first match and re-align ordering

            // Process properties
            if (preg_match('/([A-Z-]+)[;]([\w\W]*)/', $matches[0], $properties)) {
                array_shift($properties); // Remove first match
                $matches[0] = $properties[0]; // Fix to ignore everything in keyword after a ; (e.g. Language, TZID, etc.)
                array_shift($properties); // Repeat removing first match

                $formatted = [];
                foreach ($properties as $property) {
                    preg_match_all('~[^\r\n";]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^\r\n";]*)*~', $property, $attributes); // Match semicolon separator outside of quoted substrings
                    $attributes = (sizeof($attributes) == 0) ? [$property] : reset($attributes); // Remove multi-dimensional array and use the first key

                    foreach ($attributes as $attribute) {
                        preg_match_all('~[^\r\n"=]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^\r\n"=]*)*~', $attribute, $values); // Match equals sign separator outside of quoted substrings
                        $value = (sizeof($values) == 0) ? null : reset($values); // Remove multi-dimensional array and use the first key

                        if (is_array($value) && isset($value[1])) {
                            $formatted[$value[0]] = trim($value[1], '"'); // Remove double quotes from beginning and end only
                        }
                    }
                }

                $properties[0] = $formatted; // Assign the keyword property information

                array_unshift($properties, $matches[1]); // Add match to beginning of array
                $matches[1] = $properties;
            }

            return $matches;
        }

        return false; // Ignore this match
    }