PHP preg_match不会按预期返回所有值

时间:2014-06-02 11:19:50

标签: php regex preg-match

我有像:

这样的字符串
  1. postGeneratePasswordToken
  2. putUsers_VAL_Calculations_NUMBER _
  3. deleteUsers_VAL_Clients_ID _
  4. getDictionary_VAL _
  5. 我期待的结果是数组(上面的例子中的数组),其元素如下所示:

    1. 发布,生成,密码,令牌
    2. 获取,用户,_VAL_,计算,_NUMBER _
    3. 删除,用户,_VAL_,客户端,_ID _
    4. get,Dictionary,_VAL _
    5. 下面是我的代码:

      $regex = '#(post|get|put|delete)(([A-Z][a-z]+)|(_[A-Z]{2,}_))+#';
      
      $nameArray = preg_match_all($regex, $methodName, $matches);
      

      和示例输出

      array(5) {
        [0]=>
        array(1) {
          [0]=>
          string(33) "putUsers_VAL_Calculations_NUMBER_"
        }
        [1]=>
        array(1) {
          [0]=>
          string(3) "put"
        }
        [2]=>
        array(1) {
          [0]=>
          string(8) "_NUMBER_"
        }
        [3]=>
        array(1) {
          [0]=>
          string(12) "Calculations"
        }
        [4]=>
        array(1) {
          [0]=>
          string(8) "_NUMBER_"
        }
      }
      

      我知道我的正则表达式工作正常(与不同的测试人员一起检查),但我不知道如何解决这个问题,我已经阅读了preg_match的文档,并且它没有帮助,因为它是olny确实在正则表达式中返回每个组。任何想法我怎么能解决这个问题?

1 个答案:

答案 0 :(得分:1)

Any Idea how I can solve this problem?

是的,您可以像这样使用preg_split

$result = preg_split('/(?<=[a-z])(?=[A-Z])|(?=_[A-Z]*_)|(?<=_)(?=[A-Z][a-z])/', $str);

$ result数组包含你想要的字符串。

这个想法是preg_split使用的正则表达式与字符串不匹配;相反,它匹配字符串中的位置。此位置由外观定义,因此它具有零个字符。

此代码生成所需的数组(请参阅online demo底部的结果):

<?php
$regex = "~(?<=[a-z])(?=[A-Z])|(?=_[A-Z]*_)|(?<=_)(?=[A-Z][a-z])~";
print_r(preg_split($regex,"postGeneratePasswordToken"));
print_r(preg_split($regex,"putUsers_VAL_Calculations_NUMBER_"));
print_r(preg_split($regex,"deleteUsers_VAL_Clients_ID_"));
print_r(preg_split($regex,"getDictionary_VAL_"));

解释正则表达式

(?<=                     # look behind to see if there is:
  [a-z]                  #   any character of: 'a' to 'z'
)                        # end of look-behind
(?=                      # look ahead to see if there is:
  [A-Z]                  #   any character of: 'A' to 'Z'
)                        # end of look-ahead
|                        # OR
(?=                      # look ahead to see if there is:
  _                      #   '_'
  [A-Z]*                 #   any character of: 'A' to 'Z' (0 or more
                         #   times (matching the most amount
                         #   possible))
  _                      #   '_'
)                        # end of look-ahead
|                        # OR
(?<=                     # look behind to see if there is:
  _                      #   '_'
)                        # end of look-behind
(?=                      # look ahead to see if there is:
  [A-Z]                  #   any character of: 'A' to 'Z'
  [a-z]                  #   any character of: 'a' to 'z'
)                        # end of look-ahead