i want to return array from string like wordpress short code does , but i want the array to be like the example
我想从像wordpress短代码那样的字符串返回数组,但我希望数组就像这个例子
i have this string
我有这个字符串
$str = 'codes example : [code lang="php"]<?php echo "Hello Wold" ; ?>[/code] [code lang="html"]<b>Hello</b>[/code]' ;
and i want to return contain
我想要返回包含
array(
array(
'code' => '[code lang="php"]<?php echo "Hello Wold" ; ?>[/code]' ,
'function' => 'code' ,
'attr' => array( 'lang' => 'php' ) ,
'value' => '<?php echo "Hello Wold" ; ?>'
) ,
array(
'code' => '[code lang="html"]<b>Hello</b>[/code]' ,
'function' => 'code' ,
'attr' => array( 'lang' => 'html' ) ,
'value' => '<b>Hello</b>'
)
)
i tried to do it using preg_match_all
我尝试使用preg_match_all来做到这一点
i used this pattern /[[a-z]{3,}+ *[a-z]{2,}=(.*)+ *](.*)[\/[a-z]{3,}]/U
我用这个模式/ [[a-z] {3,} + * [a-z] {2,} =(。*)+ *](。*)[\ / [a-z] {3,}] / U
and the result was
结果是
Array ( [0] => Array ( [0] => [link href="http://www.php.net" text="php"][/link] [1] => [code lang="php"][/code] [2] => [code lang="html"]Hello[/code] ) [1] => Array ( [0] => " [1] => " [2] => " ) [2] => Array ( [0] => [1] => [2] => Hello ) )
数组([0] =>数组([0] => [link href =“http://www.php.net”text =“php”] [/ link] [1] => [code lang =“php “] [/ code] [2] => [code lang =”html“] Hello [/ code])[1] =>数组([0] =>”[1] =>“[2] =>” )[2] =>数组([0] => [1] => [2] =>你好))
3 个解决方案
#1
0
You can try something like this:
你可以尝试这样的事情:
preg_match_all(
'#(?P<block>\[(?P<tag>[a-z]{3,})\s*(?P<attr>[a-z-_]+="[^\]]+")*\](?P<content>((?!\[/(?P=tag)).)*)\[/(?P=tag){1}\])#',
'codes example : [code lang="php" test="true"]<?php echo "Hello Wold" ; ?>[/code] [code lang="js"]console.log(\'yeah!\')[/code] [noattr]no attr content[/noattr]',
$matches,
PREG_SET_ORDER
);
foreach ($matches as &$match) {
$match = array_intersect_key($match, array_flip(array('block', 'tag', 'attr', 'content')));;
}
print_r($matches);
result should be:
结果应该是:
Array
(
[0] => Array
(
[block] => [code lang="php" test="true"]<?php echo "Hello Wold" ; ?>[/code]
[tag] => code
[attr] => lang="php" test="true"
[content] => <?php echo "Hello Wold" ; ?>
)
[1] => Array
(
[block] => [code lang="js"]console.log('yeah!')[/code]
[tag] => code
[attr] => lang="js"
[content] => console.log('yeah!')
)
[2] => Array
(
[block] => [noattr]no attr content[/noattr]
[tag] => noattr
[attr] =>
[content] => no attr content
)
)
#2
1
You should write a parser. This may seem incredibly complex but actually it's very simple. You only need to keep track of a couple of things.
你应该写一个解析器。这可能看起来非常复杂,但实际上它非常简单。你只需要跟踪一些事情。
Outline:
- Read the string character-by-character
- If you see a
[
record that you saw it, you will now be looking for a]
- If you see a
"
before]
you will want to find another"
first. - When you see
]
you'll know the 'function' and the 'attr' - When you've found '/function' you know the 'value'
逐个字符地读取字符串
如果你看到[你看到它的记录,你现在将寻找一个]
如果你看到“之前”,你会想要找到另一个“第一个。
当你看到]你会知道'功能'和'attr'
当你找到'/ function'时你会知道'价值'
With these simple checks you can build a list of tokens, like your example output.
通过这些简单的检查,您可以构建令牌列表,例如示例输出。
#3
0
You'll want to use named groups: http://www.regular-expressions.info/named.html
您将要使用命名组:http://www.regular-expressions.info/named.html
Excerpt:
(?Pgroup) captures the match of group into the backreference "name"
(?Pgroup)将组的匹配捕获到后向引用“名称”中
EDIT: so you need to insert the named group idea into your regex.
编辑:所以你需要将命名组想法插入你的正则表达式。
#1
0
You can try something like this:
你可以尝试这样的事情:
preg_match_all(
'#(?P<block>\[(?P<tag>[a-z]{3,})\s*(?P<attr>[a-z-_]+="[^\]]+")*\](?P<content>((?!\[/(?P=tag)).)*)\[/(?P=tag){1}\])#',
'codes example : [code lang="php" test="true"]<?php echo "Hello Wold" ; ?>[/code] [code lang="js"]console.log(\'yeah!\')[/code] [noattr]no attr content[/noattr]',
$matches,
PREG_SET_ORDER
);
foreach ($matches as &$match) {
$match = array_intersect_key($match, array_flip(array('block', 'tag', 'attr', 'content')));;
}
print_r($matches);
result should be:
结果应该是:
Array
(
[0] => Array
(
[block] => [code lang="php" test="true"]<?php echo "Hello Wold" ; ?>[/code]
[tag] => code
[attr] => lang="php" test="true"
[content] => <?php echo "Hello Wold" ; ?>
)
[1] => Array
(
[block] => [code lang="js"]console.log('yeah!')[/code]
[tag] => code
[attr] => lang="js"
[content] => console.log('yeah!')
)
[2] => Array
(
[block] => [noattr]no attr content[/noattr]
[tag] => noattr
[attr] =>
[content] => no attr content
)
)
#2
1
You should write a parser. This may seem incredibly complex but actually it's very simple. You only need to keep track of a couple of things.
你应该写一个解析器。这可能看起来非常复杂,但实际上它非常简单。你只需要跟踪一些事情。
Outline:
- Read the string character-by-character
- If you see a
[
record that you saw it, you will now be looking for a]
- If you see a
"
before]
you will want to find another"
first. - When you see
]
you'll know the 'function' and the 'attr' - When you've found '/function' you know the 'value'
逐个字符地读取字符串
如果你看到[你看到它的记录,你现在将寻找一个]
如果你看到“之前”,你会想要找到另一个“第一个。
当你看到]你会知道'功能'和'attr'
当你找到'/ function'时你会知道'价值'
With these simple checks you can build a list of tokens, like your example output.
通过这些简单的检查,您可以构建令牌列表,例如示例输出。
#3
0
You'll want to use named groups: http://www.regular-expressions.info/named.html
您将要使用命名组:http://www.regular-expressions.info/named.html
Excerpt:
(?Pgroup) captures the match of group into the backreference "name"
(?Pgroup)将组的匹配捕获到后向引用“名称”中
EDIT: so you need to insert the named group idea into your regex.
编辑:所以你需要将命名组想法插入你的正则表达式。