Php 将2个正则表达式与优先级组合?

Php 将2个正则表达式与优先级组合?,php,regex,Php,Regex,我使用以下正则表达式来匹配所有1bhp或12bhp或123bhp或1234bhp。 我不知道这是否是最好的写作方式,但它确实有效 preg_match_all('/(\d{1}|\d{2}|\d{3}|\d{4})bhp/', $str2b, $bhps); 但是,如果它不匹配任何内容,我希望匹配 此 我知道这个正则表达式是!(.*?)!是 我的问题是,我很难在第一个正则表达式中确定优先级,如果未找到必和必拓的任何内容,则无法匹配始终存在的的内容 多谢各位 编辑重要信息 你们可以在这里找到一段

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

preg_match_all('/(\d{1}|\d{2}|\d{3}|\d{4})bhp/', $str2b, $bhps);
但是,如果它不匹配任何内容,我希望匹配

我知道这个正则表达式是
!(.*?)!是

我的问题是,我很难在第一个正则表达式中确定优先级,如果未找到
必和必拓
的任何内容,则无法匹配始终存在的
的内容

多谢各位

编辑重要信息

你们可以在这里找到一段HTML
第二个tr区块没有必和必拓,因此它得到下一个tr区块。因此,考虑到这一点,如果没有发现必和必拓在相同的

将与您的第一个正则表达式完全相同。如果要在正则表达式不匹配的情况下匹配div,请将其括在括号中,然后使用
将它们添加到一起。这就产生了:

'/(\d{1,4}bhp|<td class="something">(.*?)<\/td>)/'
“/(\d{1,4}bhp|(.*)/”
编辑:如果这是您想要的结果,请在此处选中:
(所有行匹配)

我想这就是您想要的:

<?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\u match\u all
将完整模式匹配放入
$bhps[0]
。如果没有匹配项,则为空。然后我们检查您的第二个正则表达式(如果是)

正如在另一个答案中提到的,您还可以通过使用
/(\d{1,4})bhp/
来修复您的第一个正则表达式以提高效率


也要考虑你是否需要或只是定期。 如果我理解得很好,这是一个包含html代码和类详细信息的示例:

这可能有效

 $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
 )
$string='1!'
#去除噪声
';
预赛(
“~(?)(?:(!)*(\d{1,4}必和必拓)(?:(!)*?(?:(!))*(?:(!)*)~s”,
$string,
$matches,
预模式顺序
);
打印($matches[1]);
------------------------
结果:
排列
(
[0]=>102bhp
[1] => 
µa/轿车
1800cc,
手册
E
Ga?????,
[2] =>1bph
)
正则表达式使用分支重置,在这里它被展开并带有边距注释-

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

(?|
(?:
(?!  )
. 
)*?
br 1(\d{1,4}bhp)#(1)
(?:
(?!  )
. 
)*?
|  
br 1(#(1开始)
(?:
(?!  )
. 
)*?
(一)(一完)
)

只需使用2
preg\u match
es即可。使用2 x
preg_match
+
if
PS:
\d{1,4}bhp
@zerkms没有什么错你能给我举个例子吗?我认为答案中提供的解决方案不正确。然而,我尝试了2场预赛,但没有运气,因为第二场比赛总是重写第一场比赛first@zerkms我已经用我的尝试编辑了这个问题。在我的HTML中有很多包含此信息的文档。如果一个人没有所有的信息,那么就有一个混乱,因为下一个去了前一个的地方。所以我每次都在尝试填充。
所以我每次都在尝试填充。
-这意味着您必须使用一个通用的开始/结束标记同时匹配这两个标记。正如你所说的一样重要的是,你没有注意到下面至少有两个答案告诉你如何去做。这将匹配两个字符串。OP只希望在第一个不匹配的情况下测试第二个。谢谢你的回答。在我的代码中,我使用fori循环,因为大约有15个tr块包含这些数据。如果一个tr区块没有所有bhp数据,则会出现混乱,因为下一个区块会转到上一个区块的位置。所以我每次都试着填满它。我对它进行了测试,我相信BHP[0]永远不会是空的…@Shilloftanos你能举个例子说明一下
$str2b
的样子吗?这将有助于得出一个答案。是的,我在这里上传了更多,有15个。中间一家没有任何必和必拓。因此,它从下一个获取必和必拓。因此,记住这一点,如果没有找到必和必拓获取位于bhp@Shilloftanos是的,我回答中的代码可以帮你做到这一点。只要用
“里程数”
替换
“某物”
,你就可以得到你想要的东西。
 $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>