parsing css measures
When i write a jQuery plugin i like to specify options for spacings the CSS way. I wrote a function that returns a CSS String as values in a object.
5px 10px returns top: 5px, right: 10px, bottom: 5px, left: 10px
Now i often use the returned values to do some calculations and its not very nice to have to extract the measuring unit every time...
I suck in writing regular expressions could someone help me complete this funct开发者_JAVA技巧ion:
this.cssMeasure = function(cssString, separateUnits){
if ( cssString ){
var values = {}
}else{
return errorMsg
}
var spacing = cssString.split(' ')
var errorMsg = 'please format your css values correctly dude'
if( spacing[4] ) {
return errorMsg
} else if ( spacing[3] ) {
values = {top: spacing[0], right:spacing[1], bottom:spacing[2], left:spacing[3]}
} else if ( spacing[2] ) {
values = {top: spacing[0], right:spacing[1], bottom:spacing[2], left:spacing[1]}
} else if ( spacing[1] ) {
values = {top: spacing[0], right:spacing[1], bottom:spacing[0], left:spacing[1]}
} else {
values = {top: spacing[0], right:spacing[0], bottom:spacing[0], left:spacing[0]}
}
if (separateUnits) {
$.each(values, function(i, value){
/*
at this place i need to extract the measuring unit of each value and return them separately
something like top: {value: 10, unit: 'px'}, right: {bla} and so on
*/
})
}
return values
}
if you have any idea how to improve this function i am open to your comments.
According to http://www.w3.org/TR/css3-values/#ltnumbergt , "A number can either be an integer, or it can be zero or more digits followed by a dot (.) followed by one or more digits", in regexp language
\d+|\d*\.\d+
Let's add an optional sign to it, and make the group "non-capturing" to make the parsing simpler
([+-]?(?:\d+|\d*\.\d+))
Enumerating all possible units is tedious, therefore let the unit be any sequence of lowercase letters (including none) or a percent sign
([a-z]*|%)
Putting it all together,
propRe = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/
When you apply this to a value
parts = "+12.34em".match(propRe)
the numeric value will be in parts[1] and the unit in parts[2]
switch (spacing.length) {
case 1:
values = {top: spacing[0], right:spacing[0], bottom:spacing[0], left:spacing[0]};
break;
case 2:
values = {top: spacing[0], right:spacing[1], bottom:spacing[0], left:spacing[1]};
break;
case 3:
values = {top: spacing[0], right:spacing[1], bottom:spacing[2], left:spacing[1]};
break;
case 4:
values = {top: spacing[0], right:spacing[1], bottom:spacing[2], left:spacing[3]};
break;
default:
return errorMsg;
}
if (separateUnits) {
values = $.map(values, function(i, value){
matches = value.match(/([-+]?[\d.]*)(.*)/);
return {value: matches[1]+0,
unit: matches[2] ? matches[2] : 'px'};
})
}
精彩评论