【问题标题】:PHP regex. How to get an array of matches?PHP 正则表达式。如何获得匹配的数组?
【发布时间】:2013-02-22 01:52:46
【问题描述】:

我有一个格式如下的字符串:

5;1-x;1-2;(1-x;)+

我使用 1-x 作为从 1 到无穷大的所有整数的符号,并使用 (1-x;)+ 来标记最后一个整数可以重复任意次数。

一些示例字符串:

5;1;1;1
5;7;2;7;5;1;9

如何将这些字符串与正则表达式匹配并获得所有 (1-x;)+ 匹配项?

我尝试了以下方法:

preg_match_all('%5;([1-9]{1}[0-9]*);([1-2]);([1-9]{1}[0-9]*;?)+%',
               $str, $matches);

字符串“5;1;1;1”的结果是:

array(4) {
  [0]=>
  array(1) {
    [0]=>
    string(7) "5;1;1;1"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  [2]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  [3]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
}

对于字符串“5;7;2;7;5;1;9”是:

array(4) {
  [0]=>
  array(1) {
    [0]=>
    string(13) "5;7;2;7;5;1;9"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "7"
  }
  [2]=>
  array(1) {
    [0]=>
    string(1) "2"
  }
  [3]=>
  array(1) {
    [0]=>
    string(1) "9"
  }
}

如您所见,只有 (1-x;)+ 中的最后一个整数在匹配数组中,但我希望匹配数组包含值 7、5、1 和 9,而不仅仅是最后一个。这甚至可以使用正则表达式还是我需要使用其他方法来验证并从这些字符串中获取值?

【问题讨论】:

  • 请解释您是如何得出需要正则表达式的结论的。
  • 我认为它比任何其他数据验证和解析字符串值的方法都更容易。
  • 也许我忽略了一些东西,但explode() 还不够吗?
  • 我之前使用正则表达式匹配格式为“1-4;1-x;1-3;1-x”的字符串,所以我想我会扩展它。如果无法将这些值放入匹配数组中,我想我将使用我已经编写的正则表达式来验证字符串格式是否正确,然后使用 explode 获取整数值。
  • 啊,我明白了,验证。您不能拥有可变数量的子模式。如果您在子模式上有一个量词,则每个匹配项都将替换最后一个匹配项,因此其最终值将仅包含其最后一个匹配项(如您所见)。

标签: php regex


【解决方案1】:

一种方式

//$str = "5;1;1;1";
$str = "5;7;2;7;5;1;9";
$pattern = '%^5;([1-9]\d*;)[12];((?:[1-9]\d*;?)+)$%';

$str = preg_replace( $pattern, '$1$2', $str, -1, $count );

if ( $count ) {
   print_r( explode( ';', $str ) );
} else {
   echo 'Invalid string';
}

-1 表示替换次数没有限制。
$count 是替换次数。如果字符串有效则为1,否则为0

以上假设如果字符串以; 结尾,它仍然有效。

【讨论】:

    【解决方案2】:

    老实说,我只会分解字符串并删除不需要的第一个和第三个元素,如下所示:

    $array = explode(';', $string);
    $diff_array = array(0 => 'not_used', 2 => 'not_used');
    $final_array = array_key_diff($array, $diff_array);
    

    这为您提供了一个包含所有值的数组,除了您似乎不感兴趣的第一个和第三个元素。

    如果您需要验证剩余元素确实是值 >= 1 的整数,您可以像这样对其运行 array_filter:

    $filtered_array = array_filter($final_array, function($value) {
        if ((string)(int)$value == $value && (int)$value >= 1) return true;
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 2012-07-24
      • 2011-03-05
      相关资源
      最近更新 更多