Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 解析CSS文件以获取包含右或左单词的选择器的单个声明_Ruby_Regex - Fatal编程技术网

Ruby 解析CSS文件以获取包含右或左单词的选择器的单个声明

Ruby 解析CSS文件以获取包含右或左单词的选择器的单个声明,ruby,regex,Ruby,Regex,我需要解析一个CSS文件,以获得在其声明(块)中包含右或左单词的单个选择器。并将选择器及其相应的声明(块)添加到数组或散列中。例如: .selector-one { /* This selector and its declaration will be added */ . . float: right; . . } #selector-two { /* This selector and its declaration will be added */ . . ma

我需要解析一个CSS文件,以获得在其声明(块)中包含右或左单词的单个选择器。并将选择器及其相应的声明(块)添加到数组或散列中。例如:

.selector-one { /* This selector and its declaration will be added */
  .
  .
float: right;
  .
  .
}

#selector-two { /* This selector and its declaration will be added */
  .
  .
margin-left: 20%;
  .
  .
}
我尝试使用扫描方法编写它,如下所示:

content.scan(/.*?\{.*?(right|left).*?\}/)

但它们中没有一个起作用

我应该提到:

  • 选择器的名称是否包含单词left或right无关紧要,我们只需要检查块

  • 选择器的名称可以以
    {
    }

  • 选择器可以分组,因此我们可以有如下内容:


我不知道ruby,但regexp应该是:

[{]([^}]*(right|left)[^}]*)[}]

根据您的示例使用ungreedy、insensitive和global标志,如果它们没有嵌套

 #  \.(selector-[^{}]*?)\s*\{([^{}]*:[ ]*(?:right|left)[ ]*;[^{}]*)\}

 \.
 ( selector- [^{}]*? )       # (1), Selector
 \s* 
 \{
 (                           # (2 start), Block
      [^{}]* 
      : [ ]* 
      (?: right | left )
      [ ]* ;
      [^{}]* 
 )                           # (2 end)
 \}
输出:

 **  Grp 0 -  ( pos 0 , len 105 ) 
.selector-one { /* This block will be added to the array */
    .
    .
float: right;
    .
    .
}  
 **  Grp 1 -  ( pos 1 , len 12 ) 
selector-one  
 **  Grp 2 -  ( pos 15 , len 89 ) 
 /* This block will be added to the array */
    .
    .
float: right;
    .
    .

----------------------

 **  Grp 0 -  ( pos 196 , len 106 ) 
.selector-three { /* This block will be added to the array */
    .
    .
float: left;
    .
    .
}  
 **  Grp 1 -  ( pos 197 , len 14 ) 
selector-three  
 **  Grp 2 -  ( pos 213 , len 88 ) 
 /* This block will be added to the array */
    .
    .
float: left;
    .
    .
Ruby在这方面很方便:

blocks = DATA.each_line
             .slice_before(/^\./)
             .map(&:join)
             .select{ |block| block[/\b(?:left|right)\b/] } 
blocks 
# => [".selector-one { /* This block will be added to the array */\n    .\n    .\nfloat: right;\n    .\n    .\n}\n\n",
#     ".selector-three { /* This block will be added to the array */\n    .\n    .\nfloat: left;\n    .\n    .\n}\n"]


__END__
.selector-one { /* This block will be added to the array */
    .
    .
float: right;
    .
    .
}

.selector-two { /* This block wont be added to the array */
    .
    .
    .
}

.selector-three { /* This block will be added to the array */
    .
    .
float: left;
    .
    .
}
  • 迭代文件中的行
  • 查看结果数组,并在正则表达式
    /^\./
    与以
    开头的行匹配时创建子数组
  • map(&:join)
    将每个子数组的内容转换回文本字符串
  • select
    查找每个字符串的内部,如果
    /\b(?:left | right)\b/
    与单词“left”或“right”匹配,则传递字符串
使用像
/\b(?:left | right)\b/
这样的模式很重要,因为正在搜索的字符串可以嵌入到较长的字符串中,如“leftover”或“bright”,并且您不希望得到假阳性


您可能以前没有见过,但它们对于这样的测试代码非常方便<代码>\uuuu END\uuuu标记脚本的结束,它之后的任何内容都可以被视为伪数据文件,可以通过
数据
访问。因此,考虑从文件中读取的代码。

,您也可以使用CSS解析器,并扫描.< /p>。 现在开始吐球代码

tree = Crass.parse(css)
nodes_with_right_or_left = tree.select do |node|
  node[:children] and node[:children].detect do |child|
    child[:value] == "right" or child[:value] == "left"
  end
end

YMMV:-)

感谢所有回答我问题的人。不幸的是,没有人能解决这个问题。下面是我如何实现它的:

input.scan(/[^{}]*\{[^}]*?(?:\Wright\W|\Wleft\W)[^}]*\}/)

关键是scan方法中的括号构成了一个捕获组。所以,我们需要把它变成一个非捕获组,使用<代码>:

我很抱歉,如果我的问题不清楚,因为我没有考虑其他方法来编写这个程序。我更新了我的问题。

tree = Crass.parse(css)
nodes_with_right_or_left = tree.select do |node|
  node[:children] and node[:children].detect do |child|
    child[:value] == "right" or child[:value] == "left"
  end
end
input.scan(/[^{}]*\{[^}]*?(?:\Wright\W|\Wleft\W)[^}]*\}/)