将2个正则表达式与优先级相结合?

时间:2013-10-14 22:53:22

标签: php regex

我使用以下正则表达式匹配所有 1bhp 12bhp 123bhp 1234bhp 。 我不知道这是否是最好的写作方式,但它确实有效。

preg_match_all('/(\d{1}|\d{2}|\d{3}|\d{4})bhp/', $str2b, $bhps);

但如果它与任何内容都不匹配,我想匹配

的内容

<td class="something">THIS</td>

我知道这个正则表达式是!<td class="something">(.*?)</td>!is

我的问题是,我在第一个正则表达式中有一个优先级很困难,如果找不到bhp的任何内容,那么匹配将始终存在的<td>的内容。

谢谢

编辑重要

您可以在此处找到一段HTML http://codepad.org/AZ4g6HDZ 第二个tr块没有bhp,所以下一个。所以考虑到这一点,如果没有找到bhp来获取同一{h}之后的<td class="mileage">this</td>

,我就没问题了

4 个答案:

答案 0 :(得分:0)

'/\d{1,4}bhp/'

与第一个正则表达式完全相同。如果那时你想匹配div,如果正则表达式不匹配,请将其包在括号中并使用|将它们添加到一起。这会创建:

'/(\d{1,4}bhp|<td class="something">(.*?)<\/td>)/'

编辑:如果这是您想要的结果,请在此处查看: http://regex101.com/r/pV1gB5(所有行匹配)

答案 1 :(得分:0)

我认为这就是你想要的:

<?php

$str2b = '<td class="something">THIS</td>';
// or maybe this: $str2b = '1234bhp';

preg_match_all('/(\d{1}|\d{2}|\d{3}|\d{4})bhp/', $str2b, $bhps);

if( empty($bhps[0]) ) {
    preg_match_all('!<td class="something">(.*?)</td>!is', $str2b, $bhps);
}


var_dump($bhps);

?>

因此,preg_match_all将完整模式匹配放入$bhps[0]。如果没有匹配,则为空。然后我们检查你的第二个正则表达式是否存在。

正如其他答案所述,您还可以使用/(\d{1,4})bhp/修复第一个正则表达式,以提高效率。

此外,您应该考虑是需要preg_match_all还是仅需preg_match

答案 2 :(得分:0)

如果我理解得很好,这是您的html代码和类详细信息的示例:

<?php
$subject = <<<'LOD'
<tr class="main_row pc">
    <td class="details">
        <div class="attribs">
            Αγροτικό/Pickup
            2500cc,
            102bhp,
            Manual,
            Πετρέλαιο,
            Ασπρο,
        </div>
    </td>
    <td class="registration">9 / 95</td>
    <td class="mileage">151.000</td>
    <td class="price">
    <span class="p_p">€ 6.300</span>
    </td>
</tr>


<tr class="main_row pc">

    <td class="details">
        <div class="attribs">
            Λιμουζίνα/Sedan
            1800cc,
            Manual,
            Βενζίνη,
            Γαλάζιο,
        </div>
    </td>
    <td class="registration">3 / 00</td>
    <td class="mileage">0</td>
    <td class="price">
    <span class="p_p">€ 900</span>
    </td>
</tr>



<tr class="main_row pc">
    <td class="details">    
        <div class="attribs">
            Αγροτικό/Pickup
            2400cc,
            1bhp,
            Manual,
            Πετρέλαιο,
            Κόκκινο,
        </div>
    </td>
    <td class="registration">1 / 95</td>
    <td class="mileage">1</td>
    <td class="price">
    <span class="p_p">€ 2.650</span>
    </td>
</tr>
LOD;

$pattern = <<<'LOD'
~ 
<td \s* class="details">\s*  
(?>
    (?> [^0-9<]++ | [0-9](?![0-9]{0,3}bhp) | <(?!/td>) )* \K
    [0-9]{1,4}bhp
  |
    \K (?> [^<]++ | <(?!/td>) )* 
)
~ix
LOD;


preg_match_all($pattern, $subject, $matches);

print_r($matches);

答案 3 :(得分:0)

这可能有效

 $string = '
       # removed to reduce noise
 ';

 preg_match_all (
  '~<td\ class="details">(?|(?:(?!</?td>).)*?(\d{1,4}bhp)(?:(?!</?td>).)*?|((?:(?!</?td>).)*?))</td>~s',
  $string,
  $matches,
  PREG_PATTERN_ORDER
 );

 print_r( $matches[1] );

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

 Result: 
 Array
 (
     [0] => 102bhp
     [1] => 
         <div class="attribs">
             ??µ?????a/Sedan
             1800cc,
             Manual,
             ?e?????,
             Ga?????,
         </div>

     [2] => 1bhp
 )

正则表达式使用分支重置,此处它已扩展并带有边距注释 -

      <td\ class="details">
      (?|
           (?:
                (?! </?td> )
                . 
           )*?
 br 1      ( \d{1,4} bhp )           # (1)
           (?:
                (?! </?td> )
                . 
           )*?
        |  
 br 1      (                         # (1 start)
                (?:
                     (?! </?td> )
                     . 
                )*?
    1      )                         # (1 end)
      )
      </td>