正则表达式哈希和冒号

时间:2013-05-09 23:01:10

标签: php regex arrays

我想使用正则表达式来过滤此字符串中的子字符串 例如: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
)

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

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

您可以使用:

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

答案 2 :(得分:2)

为你找到了一些东西:

规则:

  • 标记以#
  • 开头
  • 标签可能不包含空格/换行符
  • 标签前面跟着空格或行开头/结尾
  • 标签可以有多个部分除以:

示例:

#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 < $tag['elements']; $i++)

答案 3 :(得分:1)

这可能对您有用:

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

$parts = explode("#", $text);
foreach($parts as $part){
    $results[] = explode(":", $part);
}

var_dump($results);

答案 4 :(得分:1)

使用正则表达式的两种方法,请注意您需要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);

答案 5 :(得分:0)

这为您提供了所需的数组结构:

<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);