We can parse string character by character to eliminate classes that fall within comments /* .classe */
, is the best way to extract all CSS classes from a string.
$string = <<<EOF
div.classe1{/*comentario div.classe1b*/}
div.-classe2{/*div.-classe2b*/}
div._classe3{/*div._classe3b*/}
.classe4 div a{/*.classe4b div a*/}
.classe5.classe6{/*.classe5b.classe6b*/}
.classe7{/*......classe7b......*/}
.classe8{esse aqui nao tem comentarios mas tambem nao pega o .classe8b pois esta dentro das chaves}
.cl{/*.clb 2 caracteres*/}
.c{/*.cb 1 caractere*/}
.d{/*.db 1 caractere*/}
EOF;
$length = strlen( $string );
$brackets = false;
$comment = false;
$dot = false;
$class = '';
$classes = array();
for ( $i = 0, $j = 0; $i < $length; $i++ ) {
if ( $string[ $i ] === "\x2f" && $string[ $i + 1 ] === "\x2a" ) {
$comment = true;
continue;
} else if ( $string[ $i ] === "\x7b" ) {
$brackets = true;
continue;
} else if ( $brackets === false && $comment === false && $string[ $i ] === "\x2e" ) {
$dot = true;
continue;
} else if ( $string[ $i ] === "\x2a" && $string[ $i + 1 ] === "\x2f" ) {
$comment = false;
continue;
} else if ( $brackets === true && $string[ $i ] === "\x7d" ) {
$brackets = false;
continue;
}
if ( $dot ) {
$j = $i + 1;
$k = $j;
if ( ( ( $string[ $i ] >= "\x41" && $string[ $i ] <= "\x5a" ) || ( $string[ $i ] >= "\x61" && $string[ $i ] <= "\x7a" ) || ( $string[ $i ] === "\x2d" ) || ( $string[ $i ] === "\x5f" ) ) === false ) {
$class = '';
$dot = false;
continue;
}
$class = $string[ $i ];
while ( ( $string[ $j ] >= "\x30" && $string[ $j ] <= "\x39" ) || ( $string[ $j ] >= "\x41" && $string[ $j ] <= "\x5a" ) || ( $string[ $j ] >= "\x61" && $string[ $j ] <= "\x7a" ) || ( $string[ $j ] === "\x2d" ) || ( $string[ $j ] === "\x5f" ) ) {
$class .= $string[ $j ];
$j++;
}
array_push( $classes, $class );
$class = '';
$dot = false;
$i = $j - 1;
}
}
echo '<pre style="font-size: 14px; font-family: Consolas; line-height: 20px; tab-size: 4;">';
var_export( $classes );
echo '</pre>';
die();
The result obtained from the var_export
function is array
with all classes, and since the objective is to remove classes that will be present within comments, then this is achieved successfully and also classes are removed that exist for whatever reason inside keys (maybe this does not work well with @media css
), but I added this last because I'm assuming your code is a "normal" code without @media css
, if there is presence of% I just added the parts with @media
, in the original code I made I did not have brackets
, I have added last.
I made the code now after reading the question, I made quick tests so I can not assure you that it is working 100%, but you are extracting classes that start with brackets
or -
or _
or a-z
and proceed or not of A-Z
or -
or _
or a-z
or A-Z
.
array (
0 => 'classe1',
1 => '-classe2',
2 => '_classe3',
3 => 'classe4',
4 => 'classe5',
5 => 'classe6',
6 => 'classe7',
7 => 'classe8',
8 => 'cl',
9 => 'c',
10 => 'd',
)
PS: I know the category is Javascript and the published code is PHP, but I made a point of answering because it is the correct answer to your question and the one that obtains the best results, and also because the similarity in syntax and PHP and JS functions, to "convert" to Javascript, only minimal adaptations will be necessary. I hope I have helped.