根据https://html.spec.whatwg.org/multipage/syntax.html#attributes-2,HTML5属性名的定义如下:
属性名必须包含一个或多个字符,而不是控件、U+0020空间、U+0022 (")、U+0027 (')、U+003E (>)、U+002F (/)、U+003D (=)和非字符。
创建一个类,它可以处理或清理HTML 5属性名,我最后得到了以下代码-特别是下面的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;
}
}我的手动测试似乎很好,但我不确定正则表达式是否完全符合标准,或者我是否忘记了什么。还有什么需要改进的吗?
发布于 2021-02-26 14:24:16
\x{0020} (空格)字符已经包含在\s中,可以省略该部分。\p{Cc}而不是[:cntrl:],因为我不喜欢在字符类中嵌套正方形大括号。isAttributeNameValid()检查整个字符串是否包含黑名单中的字符。如果要匹配整个字符串,则需要“字符串的开始”和“字符串的结束”锚点和模式中的一个负值字符类。但是等等,如果字符串中有一个或多个黑名单字符,那么您将返回一个常规字符类,并且返回true --这似乎与方法名的含义正好相反。除非我感到困惑,否则您应该将(bool)替换为!,以便在匹配时返回false,在没有黑名单字符时返回true。Failed to sanitize attribute name的措辞;说Attribute name had no salvagable characters似乎更真实。https://codereview.stackexchange.com/questions/256470
复制相似问题