我有以下文字
hello <?tag?> world <?tag2?> xx <?/tag2?> hello <?/tag?> world
我需要将它转换为
阵列( '你好 ', 阵列( '世界', 阵列( 'xx' ) ' 你好 ' ) '世界' );
标签是字母数字,只要它们使用匹配的标记关闭,或<?/?>
。具有相同名称的标签可能会重复,但不会在彼此内部。
我的问题是哪种CPU效率最高?
如果你也可以提供表达,我会非常高兴。
答案 0 :(得分:1)
事实证明这并不是那么简单,但希望这可能对其他人有所帮助。最大的复杂因素是从preg_replace的回调函数返回非字符串。
感谢所有试图提供帮助的人!
class Parser {
public $ret=array();
function loadTemplateFromString($str){
$this->parsed_template=$this->tags=array();
if(!$str){
return;
}
var_dump($str);
/* First expand self-closing tags <?$tag?> -> <?tag?><?/tag?> */
$str=preg_replace('/<\?\$([\w]+)\?>/','<?\1?><?/\1?>',$str);
/* Next fix short ending tag <?tag?> <?/?> -> <?tag?> <?/?> */
$x=preg_replace_callback('/.*?<\?\/\?>/',function($x){
return preg_replace('/(.*<\?([^\/][\w]+)\?>)(.*?)(<\?\/?\?>)/',
'\1\3<?/\2?>',$x[0]);
},$str);
/* Finally recursively build tag structure */
$this->recursiveReplace($x);
}
function recursiveReplace($x){
if(is_array($x)){
// Called recursively
$tmp2=$this->ret;$this->ret=array();
}else{
$x=array(4=>$x);
$tmp2=null;
}
$y=preg_replace_callback('/(.*?)(<\?([^\/$][\w]+)\?>)(.*?)(<\?\/(\3)?\?>)(.*?)/',
array($this,'recursiveReplace'),$x[4]);
$this->ret[]=$y;
if($tmp2===null)return;
$tmp=$this->ret;
$this->ret=$tmp2;
$this->ret[]=$x[1];
$this->ret[]=$tmp;
return '';
}
}
$p=new Parser();
$p->loadTemplateFromString('bla <?name?> name <?/name?> bla bla <?$surname?> bla '.
'<?middle?> mm <?/?> blah <?outer?> you <?inner?> are <?/?> inside <?/outer?>'.
' bobobo');
var_dump($p->ret);
输出:
array
0 => string 'bla ' (length=4)
1 =>
array
0 => string ' name ' (length=6)
2 => string ' bla bla ' (length=9)
3 =>
array
0 => string '' (length=0)
4 => string ' bla ' (length=5)
5 =>
array
0 => string ' mm ' (length=4)
6 => string ' blah ' (length=6)
7 =>
array
0 => string ' you ' (length=5)
1 =>
array
0 => string ' are ' (length=5)
2 => string ' inside ' (length=8)
8 => string ' bobobo' (length=7)
答案 1 :(得分:0)
如何将<?tag
N ?>
转换为<elem
N >
并将其解析为XML?
在您看到与您提到的结果相似的原始结构之后,您可以/将根据您的元素结构进行验证(即,确保项目在数字上相互内部等)。
只需添加一个文档元素,就可以使用此样式表进行设置:
编辑:在这些标签与HTML混合的事实出现之后,我想我会改变我的策略。请在说明之前先查看以下代码:
$data = '<b>H</b>ello <?tag?> <b>W</b>orld <?/tag?>';
$conv1 = array(
// original => entity
'<?tag' => '%START-BEGIN%',
'<?/tag' => '%START-END%'
'?>' => '%END-END%'
);
$conv2 = array(
// entity => xml
'%START-BEGIN%' => '<element',
'%START-END%' => '</element'
'%END-END%' => '>'
);
$data = str_replace(array_keys($conv1), array_values($conv1), data);
$data = htmlentities($data, ENT_QUOTES); // encode HTML characters
$data = str_replace(array_values($conv2), array_keys($conv2), data);
$xml = '<?xml version="1.0" encoding="UTF-8"?>'.$data;
// You must apply the following function to each output text
// html_entity_decode($data,ENT_QUOTES);