According to https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 an HTML 5 attribute name is defined like this:
Attribute names must consist of one or more characters other than controls, U+0020 SPACE, U+0022 ("), U+0027 ('), U+003E (>), U+002F (/), U+003D (=), and noncharacters. In the HTML syntax, attribute names, even those for foreign elements, may be written with any mix of ASCII lower and ASCII upper alphas.
Creating a class which can handle or sanitize HTML 5 attribute names I have ended up with the following code - especially the following regex:
class AttributeNameValidator
{
public const ATTRIBUTE_NAME_MATCHER = "/[\s\x{0000}\x{0020}\x{0022}\x{0027}\x{003E}\x{002F}\x{003D}\x{200B}-\x{200D}\x{FDD0}-\x{FDEF}\x{FEFF}[:cntrl:]]+/u";
/**
* Checks if a given string is a valid HTML attribute name.
* @param string $attributeName
* @return bool: True if the given attribute name is a valid HTML attribute name.
*/
public static function isAttributeNameValid(string $attributeName): bool
{
return (bool)preg_match(self::ATTRIBUTE_NAME_MATCHER, $attributeName);
}
/**
* Sanitizes a string to be a valid HTML5 attribute name.
* @param string $attributeName
* @return string
* @throws NonSanitizeableException
*/
public static function sanitizeAttributeName(string $attributeName): string
{
$sanitizedAttributeName = preg_replace(self::ATTRIBUTE_NAME_MATCHER, '', $attributeName);
if(!$sanitizedAttributeName) {
throw new NonSanitizeableException("Failed to sanitize attribute name");
}
return $sanitizedAttributeName;
}
}
My manual tests seem to work well still I am not sure if the regex exactly matches the standard or if I have forgotten something. Is there still something to improve?