【问题标题】:How to make preg_match_all return an empty array value if pattern not matched?如果模式不匹配,如何使 preg_match_all 返回一个空数组值?
【发布时间】:2017-10-23 16:11:33
【问题描述】:

假设我们有以下数据,其中的代码与我们想要的模式匹配,在这种情况下,我们要捕获所有数字和 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 项,其中一项是完整的文本,在本例中为 大鸡蛋

我想要做的是让 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

【问题讨论】:

  • 我没有办法知道。如果有匹配项,您可以使用preg_match 检查并使用条件。 eval.in/885295

标签: php arrays regex


【解决方案1】:

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

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

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

}

【讨论】:

  • 你们都让我想放弃。我不喜欢你所有的思想,充满激情。这也很干净。谢谢。
【解决方案2】:

将模式修改为:

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

注意最后的“OR nothing”。

<?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) "¼"
}

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

【讨论】:

  • 啊哈,没想到这一点,我需要先停下来想想这个问题……天哪。谢谢。
  • 没问题。请记住通过标记对您最有帮助的答案来检查问题是否已回答(我认为应该是 Don't Panic's)
  • 我同意,但我从你们俩那里学到了一些新东西。再次,我很感激。
猜你喜欢
  • 1970-01-01
  • 2011-04-18
  • 2014-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多