正则表达式哈希和冒号



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

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

您可以使用:

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

do this

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

有东西给你:

规则:

  • 标签以#
  • 标签不能包含空白/换行符
  • 标记的前面和后面是空白或行开始/结束
  • 一个标签可以有几个部分,:

的例子:

#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++))

这可能适合您:

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

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

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

这给了你你正在寻找的数组结构:

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

最新更新