Я пытаюсь написать регулярное выражение, которое извлекает все шестнадцатеричные цвета из кода CSS.
Это то, что у меня есть сейчас:
Код:
$css = <<<CSS /* Do not match me: #abcdefgh; I am longer than needed. */ .foo { color: #cccaaa; background-color:#ababab; } #bar { background-color:#123456 } CSS; preg_match_all('/#(?:[0-9a-fA-F]{6})/', $css, $matches);
Вывод:
Array ( [0] => Array ( [0] => #abcdef [1] => #cccaaa [2] => #ababab [3] => #123456 ) )
Я не знаю, как указать, что будут совпадать только те цвета, которые заканчиваются пунктуацией, пробелом или новой строкой.
Поскольку шестнадцатеричный цветовой код может также состоять из 3 символов, вы можете определить обязательную группу и необязательную группу букв и цифр, поэтому длинная и продуманная нотация будет выглядеть так:
/#([af]|[AF]|[0-9]){3}(([af]|[AF]|[0-9]){3})?\b/
Или, если вам нужна хорошая и короткая версия, вы можете сказать, что хотите либо 1 или 2 группы из 3 буквенно-цифровых символов, и что они должны быть сопоставлены с регистром ( /i
).
/#([a-f0-9]{3}){1,2}\b/i
Более короткая версия ответа GolezTrol, позволяющая дважды записывать набор символов:
/#([a-fA-F0-9]{3}){1,2}\b/
В принятом ответе показано, как это сделать с регулярным выражением, потому что это был ваш вопрос. Но вам действительно не нужно использовать regex для этого. Обычно я так делаю:
if(ctype_xdigit($color) && strlen($color)==6){ // yay, it's a hex color! }
для 100 000 итераций:
Regex solution *: 0.0802619457245 секунд
Xdigit with strlen: 0.0277080535889 секунд
*: hex: ([a-fA-F0-9]{6})
Я не совсем уверен, правильно ли я прав, но если вы хотите согласовать шестнадцатеричные цвета в конце строки CSS:
preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);
должен работать, все, что я сделал, это добавить необязательный \s;
char (необязательные полутоплицы и пробелы) и символ разрыва строки (не факультативно), и это, казалось, сработало.
И как @GolezTrol указал #FFF;
также является действительным.
При тестировании на это:
$css = '/* Do not match me: #abcdefgh; I am longer than needed. */ .foo { color: #CAB; background-color:#ababab; }'; preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches); var_dump($matches);
Выход был:
array (array('#CAB;','#ababab;'))
Несмотря на возраст этого вопроса, я хотел бы изменить следующее:
^#([[:xdigit:]]{3}){1,2}$
, где [[:xdigit:]]
является сокращением для [a-fA-F0-9]
.
Так:
<?php preg_match_all("/^#([[:xdigit:]]{3}){1,2}$/", $css, $matches) ?>