【问题标题】:Multiple combinations logic should use switch or IF多重组合逻辑应使用switch或IF
【发布时间】:2017-07-05 14:08:23
【问题描述】:

我正在尝试在 switch 中存在特定字符串时编写逻辑。

例如:字符串

* * * * * 我的字符串将始终在每个字符串之间的这种格式空间中,但字符串长度会有所不同。但是 5 个空格和 5 个字符串

其他示例: 0 * * * * * 0 * * * * * 12/3 * * * * 0 0 * 0 0 * * * * * * 0 0 * * * AA 12

我在这里尝试的是在字符串存在时编写 switch case,而不是 * 我将运行 case。

switch(true):
case '0 * * * * ':
echo 'First string has value';
case '`* * 0 0 * `':
echo '3rd & 4th string has value';
case 'A B C AA 12 ':
echo 'All string has value';

等等...

我有很多组合,但我不确定 switch 是实现它的正确方法。

或逻辑 2:

我应该用空格分解字符串然后使用if条件检查5个字符串吗?

【问题讨论】:

  • 这是原理图的问题,从长远来看,切换可能会更容易,然后如果其他情况。另一种方法是使用正则表达式并计算匹配项。
  • /([^*\s]+)/ 这样的东西不匹配空格或星号regex101.com
  • 一个开关是不同的,如果 1 个 case 与下面的那些匹配,直到被 break 破坏。只需分解并验证数据,或者在需要时使用正则表达式。

标签: php logic preg-split


【解决方案1】:

类似的东西

   $total = 0;
   if( preg_match('/([^*\s]+)/', $str, $match ) ){
       $total = count( $matches[1]);
   }
    echo $total;

如果您需要知道它们的匹配位置,请改用它

   $str = '* 0 * * *';
   if( preg_match_all('/([^*\s]+)|\s/', $str, $match ) ){
       print_r( $match )
   }

结果

array (
  0 => 
  array (
    0 => ' ',
    1 => '0',
    2 => ' ',
    3 => ' ',
    4 => ' ',
  ),
  1 => 
  array (
    0 => '',
    1 => '0',
    2 => '',
    3 => '',
    4 => '',
  ),
)

这样看(从 0 开始的索引)你就知道哪些匹配了。匹配在数组索引 1 中,所以 $match[1][n],

然后你可以像这样循环遍历它

  $results = [];
   foreach( $match[1] as $m ){
      if( strlen($m) > 0 ){
          $results[] = "Match at pos $m";
      }
   }

等等……

优点是* 和其他东西的可能组合是巨大的,这标准化了,所以你只需要担心非* 的东西。想象一下,为每个可能的组合设置一个 if 的情况,这不会发生。

【讨论】:

  • 但是如果字符串是 * * * 1 21 2 * * * 两者都是 2 但实际上它们应该去不同的条件仪式,它会给出总数?
  • 我在这里尝试的是创建一个脚本来读取 crontab 命令并将它们转换为人类可编辑的文本。所以* * * * *的计时器会有很多可能性所以我应该使用switch还是if?
  • 显然,无论如何,您永远不会涵盖 * 和数字以及 `\` 的所有可能组合
  • 尽我所能..我们经常使用的..如果我使用任何新的会更新:)
  • 无法在生产中一直查看 crontab。如果能在管理员可以访问的页面中看到会很不错。
【解决方案2】:

switch 语句本质上不同于 if 语句:

switch(true){
  case true:
    echo 'true';
  case false:
    echo 'false';
  case 'foo':
    echo 'foo';
}

因此,要回答您的问题,您可能无法使用 switch 语句。 您可以使用ArtisticPhoenix's answer 中所示的正则表达式,但有时简单性也很好:

$list = [
  '0 * * * *',
  '* 0 * * *',
  '* * 12/3 * *',
  '* * 0 0 *',
  '0 0 * * *',
  '* * * 0 0',
  '* * * AA 12',
];

foreach($list as $item){
  if(count($cron = explode(' ', $item)) == 5){
    echo "Resultset of '$item'<br>";

    foreach($cron as $v){
      echo "$v<br>";
      // So I recommend if statements here.
    }
  } else {
    echo "'$item' is not in the correct format: '". implode(', ', $cron) . "'";
  }
}

【讨论】:

  • 太好了.. 将用我现有的逻辑检查这一点。
【解决方案3】:

您的问题可以/应该在没有正则表达式的情况下解决。根据您希望编写简单的英语输出的程度,您可以通过利用一些智能阵列功能来避免使用完整的条件/开关案例。考虑这种方法:

代码:(Demo)

$strings=[
    '* * * * *',
    '0 * * * *',
    '* 0 * * *',
    '* * 12/3 * *',
    '* * 0 0 *',
    '0 0 * * *',
    '* * 0 0 0',
    '* * * AA 12',
    'A B C D E'
];
$positions=['1st','2nd','3rd','4th','5th'];

foreach($strings as $s){
    $result=array_intersect_key($positions,array_diff(explode(' ',$s),['*']));
    $count=sizeof($result);
    if(!$count){
        echo "No values found in string.\n";
    }elseif($count==5){
        echo "String is full of values.\n";
    }else{
        echo "Values found in: ",implode(', ',$result),"\n";
    }
}

输出:

No values found in string.
Values found in: 1st
Values found in: 2nd
Values found in: 3rd
Values found in: 3rd, 4th
Values found in: 1st, 2nd
Values found in: 3rd, 4th, 5th
Values found in: 4th, 5th
String is full of values.

我的 3 个嵌套数组函数的执行方式如下:

  1. 在每个空格上拆分字符串(假设您的值不包含空格...如果不是这样,您应该更改值分隔符)。
  2. 从新生成的数组中删除具有以下值的元素:* 并保留键。
  3. 仅引用具有非* 值的元素,使用键查找位置名称以进行显示。

与冗长的条件繁重的替代方法相比,此方法应该大大压缩您的代码块。

【讨论】:

  • @TomPHP 我相信我已经以优于其他答案的方式简化和完善了您的任务。我的方法有什么不是你想要的吗?对于其他答案,您仍然需要运行一系列冗长的条件语句。你想要一个不同的/更好的纯英文输出吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多