solveme正则替换题

http://solveme.kr/prob/replace_filter/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
error_reporting(0);
require __DIR__.'/lib.php';
if(isset($_GET['say']) &amp;&amp; strlen($_GET['say']) < 20){
$say = preg_replace(
'/^(.*)flag(.*)$/',
'${1}<!-- FILTERED -->${2}',
$_GET['say']
);
if(preg_match('/give_me_the_flag/', $say)){
echo $flag;
}else{
echo "What does \"{$say}\" mean?";
}
echo '<hr />';
}
highlight_file(__FILE__);

于是开始思考……


_测试不难发现,匹配单词flag是从后向前的,也就是说从最后一个字符开始,替换完了一个flag之后就结束了该行代码。
如果从这个思路出发,那么被替换的flag必须位于字符串的最末尾,因为flag被代替了。
如果是这样,give_me_the_flagflag 一共长20个字符,显然不符合。
如果非要这样,就得考虑如何突破字符长度的限制,只需要再突破一个字符即可。
如果不是替换一次的话,就是一次都不替换,由于传到php解析器解析时才有代码的问题,所以问题应该在于preg_replace和pregmatch的区别。

许久之后,猛然发现,

/^(.*)flag(.*)$/

.用于任意字符匹配并不包括换行符,而且^ $界定了必须在同一行,否则匹配不到,也就是说,换行的话,可能会有惊喜。
于是成功解出。

26 hundan 1000pt 2017-07-01 15:17:53