1

我有这样的数据

 $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>

多谢你们

4

1 回答 1

2

使用环视

在这里,我们确保有一个前面的(字符,然后我们寻找我们会在日期格式中看到的文本,如您的示例。这段代码表示 ALLOW 用于字母数字字符、文字空格字符、逗号以及数字([A-Za-z ,\d]+)?。该+字符至少表示 1。它不像.*or那样贪婪.+。我用括号括起来,然后添加一个?字符使其不需要。它在逻辑上与您的| or语句类似,因为它仍然会找到年份,但我们不会通过解析另一个检查来让 PHP 做更多的工作。然后我们找到年份(总是 4 位数字{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

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

$pattern = '!(?<=\()[A-Za-z ,\d]*[\d]{4}(?=\))!';
于 2013-07-28T17:39:36.857 回答