2013-03-05 44 views
1

编辑:父类中的preg_match_all元素?

人们似乎认为我试图解析HTML,而我是重音我试图解析日志几次,和<option>结构类似到我的日志。

我的日志是这个样子:

!# [2013-03-04 14:51:31] // cluster1 BEGIN \\ 
!## apache: 41 
!## mysql: 31 
!## tomcat: 81 
!## lotus: 985 
!# [2013-03-04 14:51:56] // cluster1 END \\ 
!# [2013-03-04 14:51:56] // cluster2 BEGIN \\ 
!## apache: 13 
!## mysql: 61 
!## tomcat: 6 
!## lotus: 513 
!# [2013-03-04 14:52:13] // cluster2 END \\ 

我不能让这个正则表达式的工作,也许这是不可能的。需要帮助:)

基本上我想正则表达式来自父母实体的多个子元素。为了简洁起见,我将以下拉菜单<select> HTML元素为例。这实际上将用于日志解析,但我还不确定它将会是什么格式,并且下拉元素与我需要的非常接近,而不必解释日志的结构。

因此,让我们假设我们有一个下拉:

<select class="parent"> 
    <option value="1">First child</option> 
    <option value="2">Second child</option> 
    <option value="3">Third child</option> 
    ... 
</select> 

要单独从父<option>元素,我会使用这样的:

preg_match_all('/<select class="parent">(.*)<\/select>/is', $source, $matches); 

这是伟大的。但现在我要做的第二preg_match()过滤掉我<option>元素,所以它看起来是这样的:

preg_match_all('/<option value="(.*?)" >(.*?)<\/option>/is', $matches['1'], $finalMatches); 

而且我得到我的结果就好了。但是有没有办法将这两个命令组合成一个规则?所以它会找到父元素,在这种情况下是<select class="parent">*</select>区块,并筛选出每个在该父区中找到的<option value="*">*</option>条目?然后我会留下一组完美的父子组合,而不是迭代第一个结果,然后让每个迭代完成另一个preg_match函数。

+2

如果只有[更简单的选项](http://stackoverflow.com/questions/3577641/how-to-parse-and-process-html-xml-with-php)。 (如果你足够熟练,你可以使用正则表达式来匹配复杂的HTML,对于新手来说,它通常不是最好的选择。) – mario 2013-03-05 12:35:42

+0

在这种情况下,您需要使用'preg_replace_callback' – artnikpro 2013-03-05 12:51:33

回答

2

我认为这是你在找什么:

preg_match_all(
    '~(?:<select class="parent">|\G)\s*<option value="(.*?)">(.*?)</option>~i', 
    $source, $matches); 

\G锚匹配到以前的比赛结束位置(或输入的开始。如果没有前面的比赛)。所以第一场比赛将包括开始<select>标记和第一个<option>元素,并且每个匹配之后将包含下一个<option>元素 - 它不会跳过在后面的<select>元素中查找匹配。

Here's a demo。我还使用了\K,Match Start Reset运算符,但这不是必需的;我只是认为它使输出更易于阅读。它有效地将所有事情变成一个积极向后看,没有通常的限制。

+0

谢谢!正是我一直在寻找的 – Matt 2013-03-05 15:26:55