2

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

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

4

6 回答 6

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);
于 2013-05-09T23:18:48.973 回答
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);
于 2013-05-09T23:18:58.233 回答
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++)
于 2013-05-10T00:31:56.033 回答
1

这可能对您有用:

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

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

var_dump($results);
于 2013-05-09T23:09:47.913 回答
1

使用正则表达式的两种方法,请注意,explode()由于 PHP 的 PCRE 不支持捕获子组,因此您需要某种方式:

$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);
于 2013-05-09T23:25:14.663 回答
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);
于 2013-05-10T01:31:57.447 回答