PHP preg_match_all регулярное выражение для получения значений пикселей (с & quot; px & quot;) из css

Я ищу регулярное выражение для использования с PHP preg_match_all() функция, которая даст мне все px значения из файла CSS.

Например, если используется CSS ниже, то ожидаемый результат будет массивом:

array ( "11px", "0.45px", "11.0005px", "1.1px", "888.888px" )

$pattern Строка — это то, что у меня есть, но, похоже, она не работает.

Логика, которую я пытался использовать, такова: число перед десятичной дробью может содержать до 4 цифр, десятичный символ является необязательным, а число после десятичной дроби является необязательным, до 4 цифр, за которым следует «px».

$pattern = "/([0-9]{1,4}\.*[0-9]{1,4}*px)/";

$css = '
.some_class {
font-size: 11px;
margin-left: 0.45px;
margin-top:11.0005px;
border: 1.1px solid blue;
}
.another_class {
background: rgba(0, 0, 0, 0.2);
width: 100%;
color: #012345;
z-index: 12;
font-size: calc(100% + 888.888px);
}
';
preg_match_all($pattern, $css, $matches, PREG_PATTERN_ORDER);

3

Решение

  • группа захвата не нужна и будет только замедлять движок регулярных выражений.
  • \b обеспечит совпадение только полных квалификационных номеров
  • \d это более короткий синтаксис для [0-9],
  • чтобы соответствовать нулю или одному из чего-то использовать ?, * означает ноль или более.
  • поскольку не все значения пикселей являются числами с плавающей точкой (11px), вы можете сделать десятичные разряды цифрами и указывать от одной до четырех цифр необязательно, добавив группу без захвата и добавив нулевой или один квантификатор (?).
  • ваш шаблон ломался, потому что вы использовали два последовательных квантификатора: {1,4}* что похоже на высказывание «соответствует 1 — 4 0 или более вхождений». Движок регулярных выражений был как: «а?»

Код: (демонстрация) (Образец Демо)

$css = '
.some_class {
font-size: 11px;
margin-left: 0.45px;
margin-top:11.0005px;
border: 1.1px solid blue;
}
.another_class {
background: rgba(0, 0, 0, 0.2);
width: 100%;
color: #012345;
z-index: 12;
font-size: calc(100% + 888.888px);
}';
$pattern = "/\b\d{1,4}(?:\.\d{1,4})?px/";

var_export(preg_match_all($pattern, $css, $matches) ? $matches[0] : 'fail');

Выход:

array (
0 => '11px',
1 => '0.45px',
2 => '11.0005px',
3 => '1.1px',
4 => '888.888px',
)

Шаблоны с большей проверкой:

  • Проверяет, что перед 1-4-значным числом стоит двоеточие или пробел (\K перезапускает матч с полной строкой):

    /[: ]\K\d{1,4}(?:\.\d{1,4})?px/
    
  • Проверяет, что цифре 1-4 не предшествует цифра:

    /\D\K\d{1,4}(?:\.\d{1,4})?px/
    

Ваш пример ввода использует нули перед десятичными точками. Если нули необязательны, мой шаблон нужно будет скорректировать. Это позволит плавать без ведущей цифры, в то время как точка должна следовать за цифрой.

  1. /\D\K(?:\d{1,4}|\d{0,4}\.\d{1,4})px/

  2. /\D\K\d{0,4}(?:\.(?=\d))?\d{1,4}px/

2

Другие решения

Только что сделал исправление по вашему шаблону,

$pattern = "~([0-9]{1,4})px|([0-9]{1,4}?\.[0-9]{1,4})px~";

$css = '
.some_class {
font-size: 11px;
margin-left: 0.45px;
margin-top:11.0005px;
border: 1.1px solid blue;
}
.another_class {
background: rgba(0, 0, 0, 0.2);
width: 100%;
color: #012345;
z-index: 12;
font-size: calc(100% + 888.888px);
}
';
preg_match_all($pattern, $css, $matches, PREG_PATTERN_ORDER);

Данные в $matches:

array (
0 =>
array (
0 => '11px',
1 => '0.45px',
2 => '11.0005px',
3 => '1.1px',
4 => '888.888px',
),
1 =>
array (
0 => '11',
1 => '',
2 => '',
3 => '',
4 => '',
),
2 =>
array (
0 => '',
1 => '0.45',
2 => '11.0005',
3 => '1.1',
4 => '888.888',
),

)

1

По вопросам рекламы [email protected]