根据展示正则表达式区分相似值

时间:2014-03-29 19:50:32

标签: javascript css regex

这是我的问题:我正在研究一系列正则表达式来剖析font属性的简写css代码。以下是我到目前为止的情况:

var style = decl.val.match(/\s*(?:\s*(normal|italic|oblique)){1}/i); style = style ? style[1] : "";
var variant = decl.val.match(/\s*(?:\s*(normal|small-caps))/i); variant = variant ? variant[1] : "";
var weight = decl.val.match(/\s*((?:\s*(?:normal|bold|bolder|lighter|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px))){1})/i); weight = weight ? weight[1] : "";
var size = decl.val.match(/\/\s*((?:\s*(?:xx-small|x-small|small|medium|large|x-large|xx-large|larger|smaller|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px))){1,2})/i); size = size ? size[1] : "";
var height = decl.val.match(/\s*(?:\s*(normal|inherit|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px))){1}/i); height = height ? height[1] : "";
var family = decl.val.match(/\s*(?:\s*([a-zA-Z\-\,\'\"\s]+))(?:,|;)/i); family = family ? family[1] : "";
var values = decl.val.match(/\s*(?:\s*(caption|icon|menu|message-box|small-caption|status-bar)){1}/i); values = values ? values[1] : "";

除非我尝试使用以下字符串,否则一切都按我想要的方式工作:

font: normal small-caps 120%/120% fantasy, sans-serif;

这会导致样式,变体,重量和高度的值都设置为正常值:

style --> "normal"
variant --> "normal"
weight --> "normal"
height --> "normal"

这是因为正则表达式匹配每种情况下的第一个实例,并且不检查以确保它没有应该采取的其他值。它应该是:

style --> "normal"
variant --> "small-caps"
weight --> "120%"
height --> 

我希望这是有道理的。如果您有任何疑问,请随时发表评论。谢谢你的帮助!

2 个答案:

答案 0 :(得分:2)

重量和尺寸之间存在一些正向斜线的问题 但是你最好把它组合成一个正则表达式来制作除了
之外的所有内容 锚可选。这样可以解决问题,你不会以正常的方式结束 在大多数的变种上。

修改根据此参考http://www.w3schools.com/cssref/pr_font_font.asp
这是他们解析CSS字体速记属性的方法。

edit2 将硬空间分隔符调整为可选部分之后以及所需部分之间。

 #  /(?:(?:(normal|italic|oblique|initial|inherit)\s+)?(?:(normal|small-caps|initial|inherit)\s+)?(?:((?:normal|bold|bolder|lighter|initial|inherit|\d+))\s+)?(?:(smaller|small|x-small|xx-small|medium|larger|large|x-large|xx-large|initial|inherit|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px))(?:\/(normal|initial|inherit|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px)))?\s+)(?:(initial|inherit|(?:"[^"]*"|'[^']*'|[a-zA-Z-]+)(?:\s*,\s*(?:"[^"]*"|'[^']*'|[a-zA-Z-]+))*))|(caption|icon|menu|message-box|small-caption|status-bar|initial|inherit))/

 ####  CSS - Font Shorthand Property  
 ####  Reference:  http://www.w3schools.com/cssref/pr_font_font.asp    
 #### --------------------------------
 #### font:     

 (?:
      #### User Defined Fonts
      #### ------------------

      ##### Style (optional)
      (?:
           (                        # (1 start), Style
                normal
             |  italic
             |  oblique
             |  initial
             |  inherit 
           )                        # (1 end)
           \s+   # delimiter
      )?

      ##### Variant (optional)
      (?:
           (                        # (2 start), Variant
                normal
             |  small-caps
             |  initial
             |  inherit 
           )                        # (2 end)
           \s+   # delimiter
      )?

      ##### Weight (optional)
      (?:
           (                        # (3 start), Weight
                (?:
                     normal
                  |  bold
                  |  bolder
                  |  lighter
                  |  initial
                  |  inherit 
                  |  \d+ 
                )
           )                        # (3 end)
           \s+   # delimiter
      )?

      ##### Size (required)
      (?:
           (                        # (4 start), Size
                smaller
             |  small
             |  x-small
             |  xx-small
             |  medium
             |  larger
             |  large
             |  x-large
             |  xx-large
             |  initial
             |  inherit
             |  \d+ 
                (?: \% | in | cm | mm | em | rem | ex | pt | pc | px )
           )                        # (4 end)

           #####  Line Height (optional)
           (?:
                /                   # Separator
                (                   # (5 start), Line height
                     normal
                  |  initial
                  |  inherit
                  |  \d+ 
                     (?: \% | in | cm | mm | em | rem | ex | pt | pc | px )
                )                   # (5 end)

           )?

           \s+   # delimiter 
      )

      ##### Family (required)
      (?:
           (                        # (6 start), Family
                initial
             |  inherit
             |  (?: " [^"]* " | ' [^']* ' | [a-zA-Z-]+ )
                (?:
                     \s* , \s* 
                     (?: " [^"]* " | ' [^']* ' | [a-zA-Z-]+ )
                )*
           )                        # (6 end)
      )

   |  

      #### OR, 
      #### Use the Fonts used by these OS elements
      #### ------------------

      #### Values (required, if used)
      (                             # (7 start), Use values
           caption
        |  icon
        |  menu
        |  message-box
        |  small-caption
        |  status-bar
        |  initial
        |  inherit
      )                             # (7 end)
 )

Perl测试用例

$str = 'font:normal small-caps 120%/120% "Times New Roman", sans-serif;';

if ( $str =~ /(?:(?:(normal|italic|oblique|initial|inherit)\s+)?(?:(normal|small-caps|initial|inherit)\s+)?(?:((?:normal|bold|bolder|lighter|initial|inherit|\d+))\s+)?(?:(smaller|small|x-small|xx-small|medium|larger|large|x-large|xx-large|initial|inherit|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px))(?:\/(normal|initial|inherit|\d+(?:\%|in|cm|mm|em|rem|ex|pt|pc|px)))?\s+)(?:(initial|inherit|(?:"[^"]*"|'[^']*'|[a-zA-Z-]+)(?:\s*,\s*(?:"[^"]*"|'[^']*'|[a-zA-Z-]+))*))|(caption|icon|menu|message-box|small-caption|status-bar|initial|inherit))/)
{
    print "\nmatched  '$&'\n\n";
    print "style   = '$1'\n";
    print "variant = '$2'\n";
    print "weight  = '$3'\n";
    print "size    = '$4'\n";
    print "height  = '$5'\n";
    print "family  = '$6'\n";
    print "values  = '$7'\n";
}

输出>>

matched  'normal small-caps 120%/120% "Times New Roman", sans-serif'

style   = 'normal'
variant = 'small-caps'
weight  = ''
size    = '120%'
height  = '120%'
family  = '"Times New Roman", sans-serif'
values  = ''

答案 1 :(得分:0)

您可以做的是:

找到一个属性后,从字符串中删除此属性。然后在修改后的字符串中搜索下一个属性。

这是字符串中第一个属性的示例:

var str = decl.val;

function removeFromString(str, result) {
    console.log(result);
    return str.slice(0, result.index) + str.slice(result.index + result[0].length);
}

var style = str.match(/\s*(?:\s*(normal|italic|oblique)){1}/i); 
if(style) {
    str = removeFromString(str, style);
}
style = style ? style[1] : "";

我为此做了 jsFiddle