如果模式不匹配,如何使preg_match_all返回一个空数组值?

时间:2017-10-23 16:11:33

标签: php arrays regex

我们说我们有以下数据,代码与我们喜欢的模式相匹配,在这种情况下,我们会捕获所有数字和unicode分数。

$array = array('1 ½ cups','¼ cup','2 tablespoons', '½ cup', '1/3 cup',  '2 large', '1 ½ teaspoons', '2 tablespoons', 'Large egg', '1 teaspoon', '¼ teaspoon');

foreach($array as $arr){
    preg_match_all("/^(?:[\p{Pd}.\/\s-]*[\d↉½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅐⅛⅜⅝⅞⅑⅒⅟])+/um", $arr, $output);

    foreach($output[0] as $data){
        $try[] = $data;
    }
}

如果我们print_r($try)得到:

Array
(
    [0] => 1 ½
    [1] => ¼
    [2] => 2
    [3] => ½
    [4] => 1/3
    [5] => 2
    [6] => 1 ½
    [7] => 2
    [8] => 1
    [9] => ¼
)

数组中有11个项目,其中一个是完整文本,在此示例中为 Large egg

我尝试做的是让preg_match_all为该次迭代返回一个空值,所以我们反而得到这个:

Array
(
    [0] => 1 ½
    [1] => ¼
    [2] => 2
    [3] => ½
    [4] => 1/3
    [5] => 2
    [6] => 1 ½
    [7] => 2
    [8] =>
    [9] => 1
    [10] => ¼
)

我尝试了什么?

我查看了preg_match_all manual,但我无法找到任何可以引导我回答的内容,此时我认为可能需要在正则表达式模式,但我现在还不确定。

https://eval.in/885289

2 个答案:

答案 0 :(得分:2)

将模式修改为:

/^(?:[\p{Pd}.\/\s-]*[\d↉½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅐⅛⅜⅝⅞⅑⅒⅟]|)+/um

注意"或没有"最后。

<?php
$array = array('1 ½ cups','¼ cup','2 tablespoons', '½ cup', '1/3 cup',  '2 large', '1 ½ teaspoons', '2 tablespoons', 'Large egg', '1 teaspoon', '¼ teaspoon');

foreach($array as $arr){
    preg_match_all("/^(?:[\p{Pd}.\/\s-]*[\d↉½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅐⅛⅜⅝⅞⅑⅒⅟]|)+/um", $arr, $output);
    foreach($output[0] as $data){
        $try[] = $data;
    }
}
var_dump($try);

Demo

<强>结果:

array(11) {
  [0]=>
  string(4) "1 ½"
  [1]=>
  string(2) "¼"
  [2]=>
  string(1) "2"
  [3]=>
  string(2) "½"
  [4]=>
  string(3) "1/3"
  [5]=>
  string(1) "2"
  [6]=>
  string(4) "1 ½"
  [7]=>
  string(1) "2"
  [8]=>
  string(0) ""
  [9]=>
  string(1) "1"
  [10]=>
  string(2) "¼"
}

免责声明:这看起来像是一个可能很脆弱的肮脏黑客,但它可以让你朝着正确的方向发展

答案 1 :(得分:2)

看起来每次迭代最多只返回一次匹配,因此不需要preg_match_all内部foreach。如果没有匹配项,您可以使用preg_match并附加默认空白值。

foreach($array as $arr){
    preg_match("/^(?:[\p{Pd}.\/\s-]*[\d↉½⅓⅔¼¾⅕⅖⅗⅘⅙⅚⅐⅛⅜⅝⅞⅑⅒⅟])+/um", $arr, $output);

    $try[] = $output[0] ?? '';

}