Hoy, su tarea es escribir un programa (o una función) que acepte una cadena y genere (o devuelva) cuatro enteros.
Entrada
La cadena de entrada es un selector CSS3 y puede contener básicamente cualquier carácter Unicode.
Salida
La salida representa la especificidad CSS de este selector.
El primer número siempre es 0 (porque se usa para estilos en línea, y este ejercicio no se aplica a los estilos en línea)
El segundo número es el número de identificadores (
#foo) presentes en el selector.El tercer número es el número de clases (
.foo), atributos ([bar]) y pseudo-clases presentes en el selector.El cuarto número es el número de elementos (
biz) y pseudoelementos presentes en el selector.
Notas:
El selector universal (*) no se cuenta en ninguna parte
Los pseudo-elementos
::beforey::aftertambién se pueden escribir con un solo ":" (notación heredada)La entrada puede usar la
:not(selector)pseudoclase. El selector interno no cuenta, incluso si contiene identificadores, clases, elementos, ...)Los "ladrillos" del selector están separados por combinadores (espacios / pestañas,
+,>,~, ex:body > div+a ~*), pero también pueden acumularse (ex:div#foo.bar[baz]:hover::before)También debe manejar secuencias de escape CSS (
\seguidas de 1 a 6 números hexadecimales, seguidos de un espacio) y caracteres especiales escapados (\seguidos de cualquiera de estos!"#$%&'()*+,-./:;<=>?@[\]^`{|}~:) correctamente. Esos escapes pueden ser parte de cualquier ladrillo del selector (id, clase, etc.).No necesita hacer nada en particular si recibe un selector no válido o un selector CSS4. No te molestes en implementar un validador selector CSS3.
Aquí hay algunos enlaces para aprender más sobre CSS específicamente:
- Artículo de trucos CSS: http://css-tricks.com/specifics-on-css-specificity/
- Una herramienta (incompleta) que lo cuenta: http://specificity.keegan.st/
Ejemplos
// Universal * => 0,0,0,0 // CARNÉ DE IDENTIDAD #id => 0,1,0,0 // Clase .class => 0,0,1,0 // Atributos [foo] => 0,0,1,0 [foo = "bar"] => 0,0,1,0 [foo ~ = "bar"] => 0,0,1,0 [foo ^ = "bar"] => 0,0,1,0 [foo $ = "bar"] => 0,0,1,0 [foo * = "bar"] => 0,0,1,0 [foo | = "bar"] => 0,0,1,0 [foo = bar] => 0,0,1,0 [foo = 'bar'] => 0,0,1,0 (Nota: los corchetes [] pueden contener cualquier cosa excepto un "]" sin escape) // Pseudo-clases : raíz => 0,0,1,0 : enésimo hijo (n) => 0,0,1,0 : nth-last-child (n) => 0,0,1,0 : enésimo tipo (n) => 0,0,1,0 : enésimo último tipo (n) => 0,0,1,0 : primer hijo => 0,0,1,0 : último hijo => 0,0,1,0 : primero de tipo => 0,0,1,0 : último tipo => 0,0,1,0 : only-child => 0,0,1,0 : solo de tipo => 0,0,1,0 : vacío => 0,0,1,0 : enlace => 0,0,1,0 : visitado => 0,0,1,0 : activo => 0,0,1,0 : hover => 0,0,1,0 : foco => 0,0,1,0 : objetivo => 0,0,1,0 : lang (fr) => 0,0,1,0 : habilitado => 0,0,1,0 : deshabilitado => 0,0,1,0 : verificado => 0,0,1,0 : no (selector) => 0,0,1,0 (Nota: la palabra clave después de ":" puede ser cualquier cosa menos un pseudo-elemento) // Elementos cuerpo => 0,0,0,1 // Pseudoelementos : antes => 0,0,0,1 : después => 0,0,0,1 :: antes => 0,0,0,1 :: después => 0,0,0,1 :: primera línea => 0,0,0,1 :: primera letra => 0,0,0,1 (Nota: el paréntesis () puede contener cualquier cosa excepto un ")" sin escape)
(continuará)
Si tiene preguntas o necesita ejemplos o datos de prueba, pregunte en los comentarios.
El código más corto (en bytes) gana.
¡Buena suerte!

1sería genial. (Por cierto, creo que este es realmente un desafío bastante bueno, pero una lista exhaustiva de casos de prueba parece vital para que funcione bien.)Respuestas:
Javascript ES6
453430 bytesAquí va mi tiro!
@UPDATE mejoró el código, ahora maneja: no y: antes /: después de los selectores mejor, sin embargo, no he probado secuencias de escape CSS.
fuente