0

我使用以下正则表达式来匹配所有1bhp12bhp123bhp1234bhp。我不知道这是否是最好的写法,但它确实有效。

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 得到<td class="mileage">this</td>相同的 bhp 之后的那个,我就可以了<tr>

4

4 回答 4

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>
于 2013-10-15T01:42:07.150 回答
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);
于 2013-10-15T00:47:47.753 回答
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.

于 2013-10-14T23:25:30.290 回答
0
'/\d{1,4}bhp/'

将与您的第一个正则表达式完全相同。如果您想匹配 div 且该正则表达式不匹配,请将其括在括号中并用于|将它们添加在一起。这将创建:

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

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

于 2013-10-14T22:58:08.593 回答