正则表达式php从字符串中获取数据

时间:2013-11-20 22:33:55

标签: php regex

我想解析一个CSS文件,并且每次对{background:[some properties] right([12px)top(10px)[some properties];

进行background:[some properties] (12px) (10px) [some properties];更改

我试过这个正则表达式:

(background\s*:.*?)\s(\d+([a-z]+|%|))\s+(\d+([a-z]+|%|));

但它抓住了: background:url(../images/header.jpg) top no-repeat; height:123px; float:left; padding:65px left 0px top 0px 120px;

你可以在this fiddle中看到它应该捕获的唯一字符串是: background:url(../images/header.jpg) 10px 0 no-repeat; 但它会捕获额外的字符串。

所以我的问题是如何在;之后停止正则表达式模式,因此它不会继续下一个css规则。 和帽子是正确的模式吗?

3 个答案:

答案 0 :(得分:2)

你可以试试这个:

$result = preg_replace('/\bbackground\s*:[^;]*?\K(\d+(?:px|e[mx]|%)?+\s+)(\d+(?:px|e[mx]|%)?+)/i', 'right $1 top $2', $string);

示例:

<?php

$string = <<<'LOD'
#banner{width:814px; background:url(../images/header.jpg) top no-repeat; height:123px; float:left; padding:65px 0px 0px  120px; font-family: Georgia, "Times New Roman", Times, serif; font-size:30px; color:#fff;}

#banner2{width:814px; background:url(../images/header.jpg) 10px  0 no-repeat; height:123px; float:left; padding:65px 0px 0px  120px; font-family: Georgia, "Times New Roman", Times, serif; font-size:30px; color:#fff;}

#banner3{width:814px; background:url(../images/header.jpg) left 10px  top 0 no-repeat; height:123px; float:left; padding:65px 0px 0px  120px; font-family: Georgia, "Times New Roman", Times, serif; font-size:30px; color:#fff;}
LOD;

$result = preg_replace('/\bbackground\s*:[^;]*?\K(\d+(?:px|e[mx]|%)?+)\s+(\d+(?:px|e[mx]|%)?+)/i', 'right $1 top $2', $string);

print_r($result);

模式细节:

(?:....)是非捕获组

\K重置之前匹配结果中的所有匹配

\b是一个单词边界。这是一个零宽度断言,\w字符类的成员与另一个字符之间的边界

[^;]是一个否定字符类,表示“除;之外的所有字符”

量词在默认情况下是贪婪的(它可以捕获所有可能的),如果你希望它捕获的可能性较小(懒惰),你必须在(*?+?之后添加一个问号, ??{1,5}?

答案 1 :(得分:0)

您的正则表达式希望background属性以两个数字和;结尾,并且不希望在那里遇到no-repeat。试试这个正则表达式

(background\s*:.*?)\s(\d+([a-z]+|%|))\s+(\d+([a-z]+|%|)).*?;

答案 2 :(得分:0)

这应该有效:

(background\s*:[^;]*?)\s(\d+([a-z]+|%|))\s+(\d+([a-z]+|%|)).*?;

我已将第一个.*替换为[^;]*,或将替换为一个分号。这将阻止正则表达式遍历第一个分号,然后匹配您要查找的数值。

我还在最后的分号前添加了.*?,以允许它遍历两个数值后的任何额外数据,例如示例中的“no-repeat”。如果您愿意,.*?可以替换为[^;]*