Javascript 根据placement regex区分相似的值

Javascript 根据placement regex区分相似的值,javascript,css,regex,Javascript,Css,Regex,这是我的问题:我正在处理一系列正则表达式,以解析字体属性的简写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] : ""

这是我的问题:我正在处理一系列正则表达式,以解析字体属性的简写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 --> 

我希望这是有道理的。如果您有任何问题,请随时发表意见。谢谢你的帮助

您可以执行以下操作:

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

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

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] : "";

我为此做了一个

在重量和尺寸之间有一个小问题。
但最好是合并到一个正则表达式中,生成除
锚固件是可选的。这将把事情排成一行,你不会得到“正常”的结果
在大多数VAR上

根据此参考编辑
这就是他们解析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  = ''

这是什么*((?:大小中的额外正斜杠,一个输入错误?是否有字段可选?@sln是的,我认为额外的正斜杠可能是一个输入错误…我在复制和粘贴…所有字段都是可选的。这也适用于javascript吗?另外,当行没有以分号结尾时会发生什么?是否有办法保留空值e?就像你对pearl所做的那样?@Leinardo Smtih-很抱歉,当你发布这些评论时我不在这里。首先,我更新了我的答案,以显示浏览器如何解析字体快捷方式属性。我使用了此引用。formmated部分顶部的压缩正则表达式将与JS一起使用。而且,捕获组的数量固定为7。它们是ll占位符。这种类型的解析基本上是消除歧义的。唯一需要的字段是
Size
Family
,这足以将其余字段对齐。干杯!效果很好!我唯一需要更改的是删除字体:并将第一个\s+改为\s*,因为有些人在冒号后没有空格。这些会导致任何冲突吗?@LeinardoSmtih-是的,你不能这样做。我添加了一个edit2来解决冲突。本质上,在开始的可选部分和结束的必需部分之间需要一个空格分隔符。解决方案是在可选组中的末尾添加
\s+
,因为为了实现可选gr要匹配OUP,它们后面必须跟有所需的“大小”和“族”。这些是它们用来解析行的规则。