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