【问题标题】:Multiple Conditions in a while loop PHP一个while循环PHP中的多个条件
【发布时间】:2012-09-09 22:35:09
【问题描述】:

在while循环中使用布尔运算符具有多个条件的正确方法是什么? 我在这里有这个脚本,我觉得应该可以工作,但是当我运行它时它出现空白。

$string = '"""JOHN"" <31255555656>","DAHDI/1-1",3948723,,"",';

for ($i=0; $i<strlen($string); $i++) { 
    if ($string[$i] == chr(34)) {   
        // chr 34 is ascii value for double quote chr 44 is for comma 
        while (($string[$i] != chr(34)) && ($string[$i+1] != chr(44))) {
            echo $string[$i];
            $i++;
        }
    }

}

理想情况下,我想要的是让脚本回显给定的字符串,直到指针 ($i) 到达双引号并且它前面的一个是逗号。我觉得这很简单,我显然遗漏了一些明显的东西。

【问题讨论】:

  • 所以如果$i 位置的字符既是逗号又不是逗号,您希望代码执行吗?
  • 我真的觉得这可以通过战略性使用preg_split 和/或strtok 来解决。你能更详细地描述你的任务,而不是你的解决方案吗?
  • @lonesomeday 好吧,这里使用逗号作为分隔符。这显然有点多余,可以在if 之后立即重写为'$i++',但我认为这不是这里唯一的问题......
  • echo preg_replace('/^(.*)",/', '$1', $string);

标签: php while-loop conditional-statements boolean-operations multiple-conditions


【解决方案1】:
if ($string[$i] == chr(34)) {   
    while (($string[$i] != chr(34)) && ($string[$i+1] != chr(44))) 

如果此字符是引号,则您的 if 语句将运行。只要此字符不是引号(也不是逗号),while 语句就会一直运行

这两个是排他的。我认为您可以通过在 if 语句后增加 $i 来绕过它,但几乎可以肯定有一种更简单的方法。

【讨论】:

    【解决方案2】:

    if 和 while 表示相反的条件......这意味着 while 永远不会为真。我猜你想检查下一个字符?

    $string = '"""JOHN"" <31255555656>","DAHDI/1-1",3948723,,"",';
    
    for ($i=0; $i<strlen($string); $i++)
    { 
    
    if ($string[$i] == chr(34)) 
    
        {   
            while (($string[$i+1] != chr(34)) && ($string[$i+1] != chr(44)))  // notice the $i+1
    // chr 34 is ascii value for double quote chr 44 is for comma 
    
            {
                 echo $string[$i];
                 $i++;
    
            }
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      内部循环不会在字符串的末尾结束。

      在循环内操作循环控制变量 ($i) 会导致代码困难。 这使得推理它变得更加困难,并检查它是否正确。 你应该避免它。

      如果您只有一个循环在字符串中逐个字符移动,您将获得更好的结构。比使用变量来记住状态,例如 $inside_quotes 。

      【讨论】:

        【解决方案4】:

        你的循环中有一个逻辑缺陷,这将导致它遍历整个字符串但没有做任何输出。

        假设:

        $a = 1;
        $b = 1;
        
        while ($a == 1)
        {
            while ($a != 1 && $b == 1)
            {
                 # will never come here.
            }
        
            $a++;
        }
        

        因为$a 永远不能同时是1 和!1,而你在彼此内部设置的条件会阻止它们自己。

        解决此问题的一种常见方法是对字符串进行标记(扫描字符串),然后处理标记:

        $string = '"""JOHN"" <31255555656>","DAHDI/1-1",3948723,,"",';
        
        $token = strtok($string, '"');
        
        while ($token !== false)
        {
            $token[0] !== ',' && (print "$token\n");
        
            $token = strtok('"');
        }
        

        这会产生 (Demo) 以下输出:

        JOHN
         <31255555656>
        DAHDI/1-1
        

        这可能是也可能不是您正在寻找的东西。一个更详细的变体是拥有一个具有 state 的标记器/扫描器,它可以做更多事情(但仍然存在通过加倍 ("") 它们来转义引号的缺点)。由于这是非常虚假的,我只link它。这是假的,因为:

        您要查找的实际函数称为str_getcsv:

        $string = '"""JOHN"" <31255555656>","DAHDI/1-1",3948723,,"",';
        echo implode("\n", str_getcsv($string));
        

        输出(Demo):

        "JOHN" <31255555656>
        DAHDI/1-1
        3948723
        

        如果您有整个文件,请查看SplFileObject。

        【讨论】:

          【解决方案5】:

          由于您已经使用 for 语句找到了第一个引号,因此您无需使用 for 语句再次找到相同的引号。

          删除这个: (($string[$i] != chr(34)) && 以及额外的 ) 并且代码将产生以下内容: """约翰"" "DAHDI/1-1"

          <?php
          $string = '"""JOHN"" <31255555656>","DAHDI/1-1",3948723,,"",';
          for ($i=0; $i<strlen($string); $i++) { 
              if ($string[$i] == chr(34)) {
                  while  ($string[$i+1] != chr(44)) {
                      echo $string[$i];
                      $i++;
                  }
              }
          }
          ?>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-11-02
            • 2015-12-16
            • 2016-04-08
            • 1970-01-01
            • 2022-10-14
            • 2016-02-14
            • 1970-01-01
            相关资源
            最近更新 更多