Regex 正则表达式匹配scss函数/混合
我正在尝试匹配SCSS字符串中使用的函数或mixin,因此我可能会删除它,但我遇到了一点麻烦 对于那些不熟悉SCS的人来说,这是我试图匹配的一个例子(来自Bootstrap4) 还有一个小功能:Regex 正则表达式匹配scss函数/混合,regex,twitter-bootstrap,Regex,Twitter Bootstrap,我正在尝试匹配SCSS字符串中使用的函数或mixin,因此我可能会删除它,但我遇到了一点麻烦 对于那些不熟悉SCS的人来说,这是我试图匹配的一个例子(来自Bootstrap4) 还有一个小功能: @function str-replace($string, $search, $replace: "") { $index: str-index($string, $search); @if $index { @return str-slice($string, 1, $index -
@function str-replace($string, $search, $replace: "") {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
到目前为止,我有以下正则表达式:
@(function|mixin)\s?[[:print:]]+\n?([^\}]+)
但是,它只匹配它找到的第一个}
,这使得它失败,这是因为它需要找到最后一次出现的右大括号
我的想法是,一个能够匹配函数定义的正则表达式可以被修改,但是我用我的GoogleFoo找不到一个好的正则表达式
提前谢谢 我不建议为此使用正则表达式,因为正则表达式不能处理递归,在这种情况下您可能需要什么 例如:
@mixin test {
body {
}
}
这里包括两个»级别«({{}
),因此您的正则表达式应该能够在括号打开和关闭时计数括号,以匹配mixin或函数的结尾。但这在正则表达式中是不可能的
这个正则表达式
/@mixin(.|\s)*\}/gm
将匹配整个mixin,但如果输入如下:
@mixin foo { … }
body { … }
它将匹配到最后一个}
的所有内容,包括主体的样式定义。这是因为正则表达式无法知道哪个}
关闭mixin
看看答案,它或多或少地解释了相同的事情,但基于匹配的html元素
相反,您应该使用解析器,将整个样式表解析为语法树,然后删除不需要的函数并再次将其写入字符串。事实上,正如@philipp所说,regex不能像编译器那样取代语法分析 但这里有一个sed命令,虽然有点难看,但它可能会起作用:
sed-r-e:a'-e'N'-e'$!ba'-e's/\n//g'-e's/}\s*@(函数| mixin)/}\n@\1/g'-e's/^@(函数| mixin)\s*str replace(\s | \()+.}$//gm'
:读取循环中的所有文件并删除新行(有关详细信息,请参阅)-e':a'-e'N'-e'$!ba'-e's/\N//g'
:使每个-e's/}\s*@(function|mixin)/}\n@\1/g'
或@mixin
语句成为新行的开始,前面的@function
成为前一行的最后一个字符}
:删除与's/^@(function|mixin)\s*str replace(\s| \()++.*}$///gm'
或@function str replace
声明相对应的行@mixin str replace
我在一个文件中尝试了它,在这个文件中,我复制/粘贴了您提供的示例代码的多次,因此您必须在您的文件中尝试,因为可能有一些情况下正则表达式将匹配比所需更多的元素。如果是这样的情况,请为我们提供一个测试文件来尝试解决这些问题。在经历了许多头痛之后,这里是我问题的答案 源代码需要逐行拆分并读取,维护打开/关闭大括号的计数以确定索引何时为0
$pattern = '/(?<remove>@(function|mixin)\s?[\w-]+[$,:"\'()\s\w\d]+)/';
$subject = file_get_contents('vendor/twbs/bootstrap/scss/_variables.scss'); // just a regular SCSS file containing what I've already posted.
$lines = explode("\n",$subject);
$total_lines = count($lines);
foreach($lines as $line_no=>$line) {
if(preg_match($pattern,$line,$matches)) {
$match = $matches['remove'];
$counter = 0;
$open_braces = $closed_braces = 0;
for($i=$line_no;$i<$total_lines;$i++) {
$current = $lines[$i];
$open_braces = substr_count($current,"{");
$closed_braces = substr_count($current,"}");
$counter += ($open_braces - $closed_braces);
if($counter==0) {
$start = $line_no;
$end = $i;
foreach(range($start,$end) as $a) {
unset($lines[$a]);
} // end foreach(range)
break; // break out of this if!
} // end for loop
} // end preg_match
} // endforeach
$pattern='/(?@(函数| mixin)\s?[\w-]+[$,:“\'()\s\w\d]+)/”;
$subject=file_get_contents('vendor/twbs/bootstrap/scss/_variables.scss');//只是一个普通的scss文件,包含我已经发布的内容。
$lines=分解(“\n”,$subject);
$total_line=计数($line);
foreach($line作为$line\u no=>$line的行){
if(预匹配($pattern,$line,$matches)){
$match=$matches['remove'];
$counter=0;
$open_brates=$closed_brates=0;
对于($i=$line_no;$iThanks。不幸的是,在运行时不知道函数或mixin的名称是什么。主要的问题是,这些函数/mixin中有一些我不想匹配的变量,所以我的想法是在进行变量匹配之前去掉它们。正如我所说的,一个正则表达式是不够的。cong谢天谢地,奖牌就在岗位上。
$pattern = '/(?<remove>@(function|mixin)\s?[\w-]+[$,:"\'()\s\w\d]+)/';
$subject = file_get_contents('vendor/twbs/bootstrap/scss/_variables.scss'); // just a regular SCSS file containing what I've already posted.
$lines = explode("\n",$subject);
$total_lines = count($lines);
foreach($lines as $line_no=>$line) {
if(preg_match($pattern,$line,$matches)) {
$match = $matches['remove'];
$counter = 0;
$open_braces = $closed_braces = 0;
for($i=$line_no;$i<$total_lines;$i++) {
$current = $lines[$i];
$open_braces = substr_count($current,"{");
$closed_braces = substr_count($current,"}");
$counter += ($open_braces - $closed_braces);
if($counter==0) {
$start = $line_no;
$end = $i;
foreach(range($start,$end) as $a) {
unset($lines[$a]);
} // end foreach(range)
break; // break out of this if!
} // end for loop
} // end preg_match
} // endforeach