An unexpected output caused by misunderstood non-greedy mode of regular expression in PHP
2013-04-12 00:02
615 查看
Recently I've been working on a PHP project with my old small framework, parts of which, including the template engine, are from Discuz!. An unexpected output from the template engine surprised me.
The situation was just like the code above. It's noticed that a non-greedy operator "?" is expected to match the first {loop $thread $head} and the first {/loop}. But unfortunately it matches the first {loop $thread $head} and the second {/loop}. Non-greedy
mode seems not working. Because output1 and output2 are exactly the same.
Finally I found my solution as follows.
The non-greedy mode is kind of disordered because of the following [\r\n\t]*, which was what I didn't notice before. The regular expression engine tries to match as many as subexpressions.
<?php $input = '<html> <table> <thead>{loop $thread $head}<td>$head</td>{/loop}</thead> {loop $list2 $node} <tr>$node</tr> {/loop} </table>'; $output = preg_replace('/\{loop\s+(\S+)\s+(\S+)\}[\r\n\t]*(.+?)[\r\n\t]*\{\/loop\}/is', '<?php foreach(\\1 as \\2){?>\\3<?php }?>', $input); echo htmlspecialchars($output); $input = '<html> <table> <thead>{loop $thread $head}<td>$head</td>{/loop}</thead> {loop $list2 $node} <tr>$node</tr> {/loop} </table>'; echo '<br />'; $output = preg_replace('/\{loop\s+(\S+)\s+(\S+)\}[\r\n\t]*(.+)[\r\n\t]*\{\/loop\}/is', '<?php foreach(\\1 as \\2){?>\\3<?php }?>', $input); echo htmlspecialchars($output); ?>
The situation was just like the code above. It's noticed that a non-greedy operator "?" is expected to match the first {loop $thread $head} and the first {/loop}. But unfortunately it matches the first {loop $thread $head} and the second {/loop}. Non-greedy
mode seems not working. Because output1 and output2 are exactly the same.
Finally I found my solution as follows.
<?php $input = '<html> <table> <thead> {loop $thread $head} <td>$head</td> {/loop} </thead> {loop $list2 $node} <tr>$node</tr> {/loop} </table>'; $output = preg_replace('/\{loop\s+(\S+)\s+(\S+)\}[\r\n\t]*(.+?)[\r\n\t]*\{\/loop\}/is', '<?php foreach(\\1 as \\2){?>\\3<?php }?>', $input); echo htmlspecialchars($output); ?>
The non-greedy mode is kind of disordered because of the following [\r\n\t]*, which was what I didn't notice before. The regular expression engine tries to match as many as subexpressions.
相关文章推荐
- #1055 - Expression of SELECT list is not in GROUP BY clause and contains nonaggregated column this i
- Misleading error message in PowerShell script: "Invalid assignment expression. The left hand side of an assignment operator need
- #1055 - Expression of SELECT list is not in GROUP BY clause and contains nonaggregated column this i
- #1055 - Expression of SELECT list is not in GROUP BY clause and contains nonaggregated column this i
- php5.3 中显示Deprecated: Assigning the return value of new by reference is deprecated in 的解决方法
- ERROR 1055 (42000): Expression #1 of ORDER BY clause is not in GROUP BY..sql_mode=only_full_group_by
- [Err] 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated colum
- [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
- mysql遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题
- how to generate an analog output from a in-built pwm of Atmega 32AVR microcontrloller?
- mysql5.7 报错1055:Expression #1 of SELECT list is not in GROUP BY clause and contains non
- PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
- nginx "proxy_pass" cannot have URI part in location given by regular expression
- [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
- php5.3 中显示Deprecated: Assigning the return value of new by reference is deprecated in 的解决方法
- SELECT list is not in GROUP BY clause and contains nonaggregated column this is incompatible with sql_mode=only_full_group_by
- How do I sort an array of hashes by a value in the hash?
- SQL---Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column '
- PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
- [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated.