PHP正则匹配SCSS嵌套地图指定断点下标题字号数值问题
解决PHP preg_match匹配SCSS嵌套地图中指定断点标题字号的问题
你的正则核心问题是没有精准限制匹配范围——单行模式下无约束的.*容易跨断点/标题匹配,导致只能捕获到第一个出现的h1数值。下面是针对性的优化方案:
优化后的正则模式
针对指定断点(如large)和标题(如h3),用以下正则精准定位对应字号数值:
$pattern = "/$breakpoint:\s*\{\s*(?:(?!\}).)*?$size\s*:\s*(\d{1,3})(?:px|em|rem)?\s*;/s";
正则各部分说明
$breakpoint:\s*\{\s*:定位目标断点的起始大括号,自动跳过前后空格(?:(?!\}).)*?:非贪婪匹配,严格限制在当前断点的闭合大括号内查找,避免跨断点匹配$size\s*:\s*:定位目标标题(如h3)的属性名,兼容前后空格(\d{1,3}):捕获1-3位数字的字号核心数值(?:px|em|rem)?:可选匹配字号单位(可根据你的SCSS实际写法调整)\s*;:匹配属性末尾的分号及周边空格
PHP代码示例
假设SCSS内容存储在$scssContent变量中,循环处理所有断点和标题:
$scssContent = <<<SCSS \$header-styles: ( small: ( h1: 24px, h2: 20px, h3: 18px ), large: ( h1: 48px, h2: 36px, h3: 32px ), xxlarge: ( h1: 64px, h2: 48px, h3: 40px ) ); SCSS; $breakpoints = ['small', 'large', 'xxlarge']; $sizes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; foreach ($breakpoints as $breakpoint) { foreach ($sizes as $size) { // 对特殊字符转义,避免正则语法冲突 $safeBreakpoint = preg_quote($breakpoint, '/'); $safeSize = preg_quote($size, '/'); $pattern = "/$safeBreakpoint:\s*\{\s*(?:(?!\}).)*?$safeSize\s*:\s*(\d{1,3})(?:px|em|rem)?\s*;/s"; if (preg_match($pattern, $scssContent, $matches)) { echo "{$breakpoint}下{$size}的字号:{$matches[1]}\n"; // 如需替换为新值,使用preg_replace: // $newSize = 50; // $scssContent = preg_replace($pattern, "$safeBreakpoint: {\\1$safeSize: {$newSize}px;", $scssContent); } } }
关键注意事项
- 禁止无限制
.*:单行模式下.*会匹配到文件末尾,必须用(?:(?!\}).)*?锁定当前断点的块范围 - 处理特殊字符:如果断点/标题包含正则特殊符号(如连字符),必须用
preg_quote()转义 - 兼容单位:根据你的SCSS实际写法调整单位匹配规则,避免漏捕或误判
内容的提问来源于stack exchange,提问作者RyanHirliman
相关产品推荐
相关产品推荐

