【问题标题】:improve preg / pcre / regex to find PHP variable改进 preg / pcre / regex 以查找 PHP 变量
【发布时间】:2013-07-26 07:27:19
【问题描述】:

要解析的字符串:

$str = "
public   $xxxx123;
private  $_priv   ;
         $xxx     = 'test';
private  $arr_123 = array();
"; //    |       |
   //     ^^^^^^^---- get the variable name

我得到了什么

    $str = preg_match_all('/\$\S+(;|[[:space:]])/', $str, $matches);
    foreach ($matches[0] as $match) {
        $match = str_replace('$', '', $match);
        $match = str_replace(';', '', $match);
     }

它有效,但我想知道我是否可以改善怀孕,例如摆脱这两个str_replace 并可能在(;|[[:space:]]) 中包含\t

【问题讨论】:

    标签: php regex preg-match-all pcre


    【解决方案1】:

    使用积极的向后看,您可以获得您需要的东西,以确保您只会匹配有效变量名称,我使用了这个:

    preg_match_all('/(?<=\$)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',$str,$matches);
    var_dump($matches);
    

    正确显示:

    大批 ( 0 => 大批 ( 0 => 'xxxx123', 1 => '_priv', 2 => 'xxx', 3 => 'arr_123' ) )

    这就是你所需要的,在包含所有变量及其前导和/或尾随字符的数组上没有内存。

    表达式:

    • (?&lt;=\$) 是一个积极的回顾
    • [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*: 是正则表达式 PHP 的网站建议自己 on their document pages

    【讨论】:

    • 这也会匹配其他随机字符串,如 $("=§/&="§/$。它也不会正确匹配 $x=123;
    • 仍然会匹配例如这里 "!"§$%&/()=?`" -> $%&/()
    • @andreasLinden:我已经编辑了我的答案,现在使用正则表达式 PHP 建议自己只匹配有效的变量名
    • 好的,现在缺少什么来获得完美的解决方案:排除单引号字符串中的变量:D
    • @AndreasLinden:这会有点棘手,因为环视必须是固定长度的,但话又说回来,你可以只用preg_replace('/(?&lt;=\')(.*)\$/', '$1', $str); 从单引号字符串中删除所有$跨度>
    【解决方案2】:

    只需使用反向引用

    preg_match_all('/\$(\S+?)[;\s=]/', $str, $matches);
    foreach ($matches[1] as $match) {
    
         // $match is now only the name of the variable without $ and ;
    }
    

    【讨论】:

      【解决方案3】:

      我稍微改了一下正则表达式,看看:

      $str = '
      public   $xxxx123;
      private  $_priv   ;
               $xxx     = "test";
      private  $arr_123 = array();
      ';
      
      $matches = array();
      
      //$str = preg_match_all('/\$(\S+)[; ]/', $str, $matches);
      $str = preg_match_all('/\$(\S+?)(?:[=;]|\s+)/', $str, $matches); //credits for mr. @booobs for this regex
      
      print_r($matches);
      

      输出:

      Array
      (
          [0] => Array
              (
                  [0] => $xxxx123;
                  [1] => $_priv 
                  [2] => $xxx 
                  [3] => $arr_123 
              )
      
          [1] => Array
              (
                  [0] => xxxx123
                  [1] => _priv
                  [2] => xxx
                  [3] => arr_123
              )
      
      )
      

      现在您可以在 foreach 循环中使用$matches[1]

      ::更新::

      使用正则表达式 "/\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/" 后,输出看起来正确。

      字符串:

      $str = '
      public   $xxxx123; $input1;$input3
      private  $_priv   ;
               $xxx     = "test";
      private  $arr_123 = array();
      

      ';

      还有输出:

      Array
      (
          [0] => Array
              (
                  [0] => $xxxx123
                  [1] => $input1
                  [2] => $input3
                  [3] => $_priv
                  [4] => $xxx
                  [5] => $arr_123
              )
      
          [1] => Array
              (
                  [0] => xxxx123
                  [1] => input1
                  [2] => input3
                  [3] => _priv
                  [4] => xxx
                  [5] => arr_123
              )
      
      )
      

      【讨论】:

      • 我会更多地更改正则表达式,以便即使在赋值运算符之前没有空格也可以匹配:\$(\S+?)(?:[=;]|\s+)
      • 这里的问题:$input; $input2; 它不匹配 $input2;
      • @sbooob 不错,我会更改正则表达式。
      • @DanFromGermany 我没有这个问题吗?你用的是什么字符串?
      • 这个简单的方法似乎可行:/\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/。 “简单”,因为它只是根据PHP manual 的有效 PHP var 名称的正则表达式
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多