2010-05-11 8 views
28

Quels sont les caractères (complets) valides charset caractères pour les identificateurs CSS id et class?Caractères autorisés pour les identificateurs CSS

Existe-t-il une expression régulière que je peux utiliser pour valider? Est-ce que c'est un navigateur agnostique?

+3

duplication possible de [Quels caractères sont valides dans les noms de classes CSS?] (Http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names) – mercator

+0

@mercator: Aussi votant pour fermer. =) –

+2

Cette question semble être une copie de s.o.Q448981: [Quels caractères sont valides dans les noms de classes CSS?] (Http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names) –

Répondre

41

Le jeu de caractères n'a pas d'importance. Les caractères autorisés sont plus importants. Vérifiez le CSS specification. Voilà une cite de pertinence:

En CSS, les identifiants (y compris les noms d'éléments, les classes et les ID dans selectors) ne peuvent contenir que les caractères [a-zA-Z0-9] et caractères ISO 10646 U+00A1 et supérieur, ainsi que le trait d'union (-) et la souligner (_); ils ne peuvent pas commencer par un chiffre ou un trait d'union suivi d'un chiffre. Les identificateurs peuvent également contenir des caractères échappés et tout caractère ISO 10646 sous la forme d'un code numérique (voir l'élément suivant). Par exemple, l'identifiant "B&W?" peut être écrit "B\&W\?" ou "B\26 W\3F".

Mise à jour: Quant à la question regex, vous pouvez trouver la grammaire here:

ident  -?{nmstart}{nmchar}* 

qui contient des parties:

nmstart [_a-z]|{nonascii}|{escape} 
nmchar  [_a-z0-9-]|{nonascii}|{escape} 
nonascii [\240-\377] 
escape  {unicode}|\\[^\r\n\f0-9a-f] 
unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])? 
h   [0-9a-f] 

Cela peut se traduire à Java regex comme suit (j'ai seulement ajouté des parenthèses aux parties contenant le OU et échappé aux barres obliques inverses):

String h = "[0-9a-f]"; 
String unicode = "\\\\{h}{1,6}(\\r\\n|[ \\t\\r\\n\\f])?".replace("{h}", h); 
String escape = "({unicode}|\\\\[^\\r\\n\\f0-9a-f])".replace("{unicode}", unicode); 
String nonascii = "[\\240-\\377]"; 
String nmchar = "([_a-z0-9-]|{nonascii}|{escape})".replace("{nonascii}", nonascii).replace("{escape}", escape); 
String nmstart = "([_a-z]|{nonascii}|{escape})".replace("{nonascii}", nonascii).replace("{escape}", escape); 
String ident = "-?{nmstart}{nmchar}*".replace("{nmstart}", nmstart).replace("{nmchar}", nmchar); 

System.out.println(ident); // The full regex. 

Mise à jour 2: oh, vous êtes plus un PHP'er, eh bien je pense que vous pouvez comprendre comment/où faire str_replace?

+1

"l'identifiant" B & W? " peut être écrit "B \ & W \?" ou "B \ 26 W \ 3F" "- Mais personne ne fait cela, et je suis content qu'ils ne le fassent pas. :-) – amphetamachine

+0

MERCI! C'est juste génial! : D Je pensais que c'était très limité mais je ne savais pas que je pouvais utiliser '\' comme caractère d'échappement. Est-ce que quelqu'un a déjà construit une regex pour valider les caractères autorisés? –

+0

C'est parfait, et oui je peux le comprendre. =) Merci encore! –

0

Ceci est simplement une contribution à la réponse de @BalusC. C'est la version PHP du code Java qu'il a fourni, je l'ai converti et j'ai pensé que quelqu'un d'autre pourrait trouver cela utile.

$h = "[0-9a-f]"; 
$unicode = str_replace("{h}", $h, "\{h}{1,6}(\r\n|[ \t\r\n\f])?"); 
$escape = str_replace("{unicode}", $unicode, "({unicode}|\[^\r\n\f0-9a-f])"); 
$nonascii = "[\240-\377]"; 
$nmchar = str_replace(array("{nonascii}", "{escape}"), array($nonascii, $escape), "([_a-z0-9-]|{nonascii}|{escape})"); 
$nmstart = str_replace(array("{nonascii}", "{escape}"), array($nonascii, $escape), "([_a-z]|{nonascii}|{escape})"); 
$ident = str_replace(array("{nmstart}", "{nmchar}"), array($nmstart, $nmchar), "-?{nmstart}{nmchar}*"); 


echo $ident; // The full regex. 
1

Pour ceux qui recherchent quelque chose d'un peu plus clé en main. La pleine expression, remplacé et tout, de @ réponse de BalusC est:

/-?([_a-z]|[\240-\377]|([0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|[^\r\n\f0-9a-f]))([_a-z0-9-]|[\240-\377]|([0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|[^\r\n\f0-9a-f]))*/ 

Et en utilisant DEFINE, que je trouve un peu plus lisible:

/(?(DEFINE) 
    (?P<h>  [0-9a-f]       ) 
    (?P<unicode> (?&h){1,6}(\r\n|[ \t\r\n\f])?  ) 
    (?P<escape> ((?&unicode)|[^\r\n\f0-9a-f])*  ) 
    (?P<nonascii> [\240-\377]       ) 
    (?P<nmchar> ([_a-z0-9-]|(?&nonascii)|(?&escape))) 
    (?P<nmstart> ([_a-z]|(?&nonascii)|(?&escape)) ) 
    (?P<ident> -?(?&nmstart)(?&nmchar)*   ) 
) (?: 
    (?&ident) 
)/x 

Soit dit en passant, l'expression régulière originale (et @ de l'homme contribution) avait quelques caractères d'échappement voyous qui permettent [ dans le nom. En outre, il convient de noter que l'expression rationnelle brute sans, DEFINE, s'exécute environ 2x plus vite que l'expression DEFINE, en prenant seulement ~ 23 étapes pour identifier un seul caractère Unicode, tandis que la dernière prend ~ 40.

Questions connexes