【问题标题】:Regex hash and colons正则表达式哈希和冒号
【发布时间】:2013-05-04 13:34:19
【问题描述】:

我想使用正则表达式来过滤这个字符串中的子字符串 例如:hello world #level:basic #lang:java:php #...

我正在尝试生成一个结构如下的数组:

Array 
(
    [0]=> hello world
    [1]=> Array 
          (
              [0]=> level
              [1]=> basic
          )
    [2]=> Array 
          (
              [0]=> lang
              [1]=> java
              [2]=> php
          )
)

我试过preg_match("/(.*)#(.*)[:(.*)]*/", $input_line, $output_array);

而我得到的是:

Array
(
    [0] => hello world #level:basic #lang:java:php
    [1] => hello world #level:basic 
    [2] => lang:java:php
)

在这种情况下,我将不得不多次将此正则表达式应用于索引,然后应用正则表达式将冒号过滤掉。我的问题是:是否有可能创建一个更好的正则表达式来一次性完成所有工作?正则表达式是什么?谢谢

【问题讨论】:

  • 改用explode
  • 语法不清楚。遇到哈希后,比赛应该什么时候结束?在下一个哈希?如果是这样,您不能在最后一个哈希之后放置任何“正常”文本,因为它将被视为其中的一部分。您需要收紧语法。

标签: php regex arrays


【解决方案1】:

你可以使用:

$array = explode("#", "hello world #level:basic #lang:java:php");
foreach($array as $k => &$v) {
    $v = strpos($v, ":") === false ? $v : explode(":", $v);
}
print_r($array);

【讨论】:

  • 谢谢,您的回答非常简洁、简短,并按照我的要求返回一个数组。我也喜欢通过参考部分传递。只是一个简单的问题,如果我希望“hello world”部分灵活,可以在任何地方,这可能吗?
【解决方案2】:

这样做

$array = array() ;
$text = "hello world #level:basic #lang:java:php";

$array = explode("#", $text);
foreach($array as $i => $value){
    $array[$i] = explode(":", trim($value));
}

print_r($array);

【讨论】:

    【解决方案3】:

    有东西给你:

    规则:

    • 标签以# 开头
    • 标签不能包含空格/换行符
    • 一个标签之前和之后是空格或行开头/结尾
    • 标签可以有几个部分除以:

    例子:

    #this:tag:matches this is some text #a-tag this is no tag: \#escaped
    and this one tag#does:not:match
    

    功能:

    <?php
    function parseTags($string)
    {
        static $tag_regex = '@(?<=\s|^)#([^\:\s]+)(?:\:([^\s]+))*(?=\s|$)@m';
    
        $results = array();
        preg_match_all($tag_regex, $string, $results, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
    
        $tags = array();
        foreach($results as $result) {
            $tag = array(
                'offset' => $result[0][1],
                'raw' => $result[0][0],
                'length' => strlen($result[0][0]),
                0 => $result[1][0]);
            if(isset($result[2]))
                $tag = array_merge($tag, explode(':', $result[2][0]));
    
            $tag['elements'] = count($tag)-3;
            $tags[] = $tag;
        }
    
        return $tags;
    }
    ?>
    

    结果:

    array(2) {
      [0]=>array(7) {
        ["offset"]=>int(0)
        ["raw"]=>string(17) "#this:tag:matches"
        ["length"]=>int(17)
        [0]=>string(4) "this"
        [1]=>string(3) "tag"
        [2]=>string(7) "matches"
        ["elements"]=>int(3)
      }
      [1]=>array(5) {
        ["offset"]=>int(36)
        ["raw"]=>string(6) "#a-tag"
        ["length"]=>int(6)
        [0]=>string(5) "a-tag"
        ["elements"]=>int(1)
      }
    }
    

    每个匹配的标签包含

    • 原始标签文本
    • 标签偏移量和原始长度(例如,稍后用str...函数替换它在字符串中)
    • 元素的数量(安全迭代for($i = 0; $i &lt; $tag['elements']; $i++)

    【讨论】:

      【解决方案4】:

      这可能对你有用:

      $results = array() ;
      $text = "hello world #level:basic #lang:java:php" ;
      
      $parts = explode("#", $text);
      foreach($parts as $part){
          $results[] = explode(":", $part);
      }
      
      var_dump($results);
      

      【讨论】:

      • 建议:用"#" 代替" #",然后trim 每个结果。
      【解决方案5】:

      两种使用正则表达式的方法,注意你需要explode(),因为PHP的PCRE不支持capturing a subgroup

      $string = 'hello world #level:basic #lang:java:php';
      preg_match_all('/(?<=#)[\w:]+/', $string, $m);
      foreach($m[0] as $v){
          $example1[] = explode(':', $v);
      }
      print_r($example1);
      
      
      // This one needs PHP 5.3+
      $example2 = array();
      preg_replace_callback('/(?<=#)[\w:]+/', function($m)use(&$example2){
          $example2[] = explode(':', $m[0]);
      }, $string);
      print_r($example2);
      

      【讨论】:

        【解决方案6】:

        这为您提供了您正在寻找的数组结构:

        <pre><?php
        $subject = 'hello world #level:basic #lang:java:php';
        $array = explode('#', $subject);
        foreach($array as &$value) {
            $items = explode(':', trim($value));
            if (sizeof($items)>1) $value = $items;
        }
        print_r($array);
        

        但如果你愿意,你可以使用这个可憎的:

        $subject = 'hello world #level:basic #lang:java:php';
        $pattern = '~(?:^| ?+#)|(?:\G([^#:]+?)(?=:| #|$)|:)+~';
        preg_match_all($pattern, $subject, $matches);
        
        array_shift($matches[1]);
        $lastKey = sizeof($matches[1])-1;
        
        foreach ($matches[1] as $key=>$match) {
            if (!empty($match)) $temp[]=$match;        
            if (empty($match) || $key==$lastKey) {
                $result[] = (sizeof($temp)>1) ? $temp : $temp[0];
                unset($temp);
            }
        }
        
        print_r($result);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-12
          • 2013-01-26
          • 2021-03-12
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          相关资源
          最近更新 更多