регулярное выражение строки JavaScript (проверка правильности CSS + преобразование) - PullRequest
3 голосов
/ 13 апреля 2011

с учетом строки, такой как один из следующих:

'2'
'2px'
'2%'
'2em'
'2foobar'
'foobar'

Я хотел бы определить:

1), является ли это простым числом (2 или 2,2), и еслион округляется (Math.floor ()) и добавляет к нему «px», так что «2» или «2.2» становится «2px»

2), если это не простое число, определите,является допустимым значением css, то есть если оно состоит из числа (int или float), за которым следуют «px», «em» или «%».Я знаю, что есть другие, но я просто поддержу этих троих.Если это так, оставьте его.

3), если нет, посмотрите, начинается ли строка с числа (int ot float), округлите его и добавьте 'px'

4), а если нетустановите пустую строку

, чтобы результат был:

'2'     -> '2px'
'2.2'   -> '2px'

'2%'    -> '2%'
'2em'   -> '2em'

'2foo' -> '2px'

'foo'  -> ''

Возможно ли сделать это компактным способом (возможно, с помощью регулярных выражений), или с использованием существующегобиблиотека валидатора css для JS?

Ответы [ 7 ]

7 голосов
/ 13 апреля 2011

Вот как с регулярным выражением:

var input = '2.7em', output = parseInt(input) + (input.match(/px|%|em/) || 'px')

edit:

var input = '2.7foo'
, number = parseInt(input)
, output = (isNaN(number)) ? '': number + (input.match(/px|%|em/) || 'px');

edit 2: разрешить плавать с em и%:

var inp='3.5em'
, n=parseFloat(inp), p=inp.match(/%|em/)
, output = (isNaN(n)) ? '': (p)?n+p:Math.round(n)+'px';
2 голосов
/ 13 апреля 2011
var input  = '2foo';
var output = '';
var tmp;

tmp = parseInt( input.replace(/^[^1-9]*/, '') );
if ( tmp != 'NaN' ) {
  if ( tmp + '%' == input ) {
    output = tmp + '%';
  } else if ( tmp + 'em' == input ) {
    output = tmp + 'em';
  } else {
    output = tmp + 'px';
  }
}
0 голосов
/ 28 декабря 2015

Конечно, вы спрашивали о регулярном выражении ... В любом случае, это также возможно путем анализа значения как int или float и вычитания его из исходного значения.

var input = '2.2px';
var value = parseInt(input) // => 2
var unit = input.split(value)[1] // => 'px'
0 голосов
/ 14 апреля 2011

Думал, что выложу решение, которое использую сейчас.Jus опубликовал в качестве ответа, чтобы получить синтаксис окраски.Эту вещь можно проверить здесь: http://jsfiddle.net/385AY/2/

Это очень долго, и некоторые решения здесь гораздо более компактны ... но для тех, кто может использовать его, есть версия, которая более доступнадля начинающих, так и с комментариями ..

function css_value_validate(input) {

    // first get rid of any whitespace at beginning or end of sting
    input = $.trim(input);

    // now catch any keywords that should be allowed
    // this could be expanded for lots of keyword 
    // by holding allowed words in an object and 
    // checking against them
    if (input == 'auto') {
        return input;
    }

    // now get rid of anything that may precede the first occurence of a number or a dot 
    input = input.replace(/^[^0-9\.]*/, '');

    // add a leading zero if the input starts with a . and then a number
    input = input.replace(/(^\.[0-9]*)/, "0$1");

    var output = '';
    var numeric;

    // check of the input is a straight zero or an empty string and 
    if (input + '' === '0' || input + '' === '') {
        return input;
    }

    // get the raw numeric by parsing to float
    numeric = parseFloat(input);
    if (numeric != 'NaN') {
        if (numeric + '%' === input) {
            output = numeric + '%';
        } else if (numeric + 'em' === input) {
            output = numeric + 'em';
        } else {
            // if converted to pixels strip any decimals.
            // the 2nd parameter, 10, is the radix making sure we parse in decimal
            output = parseInt(numeric, 10);
            output = (output > 0) ? output + unit : output;
        }
    }

    return output;
} // END cssvalidate()
0 голосов
/ 14 апреля 2011

Интересная проблема.Вот проверенное решение, которое использует одно регулярное выражение и оператор switch:

function clean_css_value(text) {
    var re = /^(\d+(?:\.\d*)?|\.\d+)([^\d\s]+)?$/m;
    // Case 0: String does not match pattern at all.
    if (!(m = text.match(re))) return '';
    // Case 1: No number at all? return '';
    if (!m[1]) return '';
    var i = Math.floor(m[1]); // Compute integer portion.
    // Case 2: Nothing after number? return integer pixels
    if (!m[2]) return i + 'px';
    switch (m[2]) {
    case 'em':
    case '%':
        return m[1] + m[2];
    case 'px':
    default:
        return i + 'px';
    }
}

Обратите внимание, что эта функция также работает для дробных чисел, не имеющих целочисленной части, например .2px.

0 голосов
/ 13 апреля 2011

Если вы используете это регулярное выражение для замены своих данных, вам нужно использовать только те, у которых отсутствует префикс.

^((?<whole>\d+)(\.\d+){0,1}(?<valid>px|em|pt|%){0,1}.*|.*)$

Сначала замените это на

${whole}${valid}

Если регулярное выражение не сопоставлено, вторая часть (|. *) Будет сопоставлена ​​(что угодно), и совпадение будет заменено ничем.

Вы также можете переходить строка за строкой и удалять эту часть, если нет совпадения, поменять ее в javascript с помощью ''.

Наконец, просто выполните быструю замену, используя

^(?<justdigits>\d+)$

и заменить на

${justdigits}px

Итак, вкратце: множество способов сделать это, до вас, как продолжить.

0 голосов
/ 13 апреля 2011

Есть несколько CSS-парсеров, написанных на JS, не уверен, насколько они хороши при разборе чисел. Regex может быть вашим лучшим вариантом.

https://github.com/stubbornella/parser-lib

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...