大括号内的preg_match有时可选择在大括号内存在其他内容

时间:2013-07-28 17:28:27

标签: php regex

我有这样的数据

 $data =  '<a href="not important"><span class="theclass">data (not important)</span></a> <span class="anotherclass">extra data (October 1, 2010)</span>';

我想在大括号内得到日期,所以我做了以下preg_match

preg_match("/\((([a-zA-Z]{5,10} .*?)|(\d{4}))\)/i",$data,$res);

请注意,有时'10月1日'不存在但今年总是存在因此OR条件....事情是它在这种情况下给我3个数组,我知道它因为3的一组我对每种情况都有支撑,有没有其他更好更清洁的方法来实现这一目标?

第二条件方法

   $data =  <a href="not important"><span class="theclass">data</span></a> <span class="theother">data <a href="not importand">data</a>  (2009)</span>
        </h3>

谢谢你们

1 个答案:

答案 0 :(得分:2)

使用lookarounds

这里我们确保有一个前面的(字符,然后我们会查找我们会在格式化的示例中看到的文字。这一小段代码表示允许使用字母数字字符,文字空格字符和逗号,以及数字([A-Za-z ,\d]+)?+字符表示至少为1 。它并不像.*.+那样贪婪。我用括号括起来然后添加?字符以使其不是必需的。它在逻辑上与您的| 语句类似,因为它仍然会找到年份,但我们不会通过解析另一个检查来使PHP做更多工作。然后我们找到年份(总是4位{​​{1}})。然后我们检查以确保它后跟一个文字{4}字符。 )后面的外观和前瞻(?<=\()会找到一个匹配项,但它们不会包含在匹配结果中,让您的答案保持清晰。

由于preg_match()返回(?=\)),我们正在捕获数组中的第一个元素。如果您在同一个字符串中查找多个匹配项,则可以使用array()

preg_match_all

<强>输出

$data =  '<a href="not important">
   <span class="theclass">data (not important)</span></a>
   <span class="anotherclass">extra data (October 1, 2010)</span>
   <span class="anotherclass">extra data (2011)</span>';
$pattern = '!(?<=\()([A-Za-z ,\d]+)?[\d]{4}(?=\))!';
$res = preg_match_all($pattern,$data,$myDate);

print_r($myDate[0]);

如果您只想查找一个匹配项,则可以将代码更改为:

Array
(
    [0] => October 1, 2010
    [1] => 2011
)

<强>输出

$res = preg_match($pattern,$data,$myDate);

echo($myDate[0]);

编写模式的另一种方法就是这样......我们删除了括号(分组)和加号October 1, 2010 修饰符,后跟条件+,但是保留了第一组。然后我们使用?使其成为条件。区别在于preg_match和preg_match_all,任何分组也存储在数组中。由于这不是一个组,因此它不会存储额外的数组元素。

*