功能介绍
给定一个正则,生成php的正则调用代码。
一般正则中都会或多或少的包含具体编程语言中的特殊字符,还需要考虑到具体语言中字符串的转义;
下面列出了一些常见的要考虑的情况:
1. 语言是否支持多行字符串
2. 是否有定界符
3. 语言的正则引擎是否支持逆序环视
4. 正则修正符
具体场景
我们拿PHP做个例子:
写一个特殊字符覆盖比较全的正则,并写出他的PHP匹配代码:
要匹配的内容
<!-- 模拟一个要匹配的字符串, 我们要取出其中的<div/>区块的内容 --> <article> <div class="quote">'引用/'</div> </article>正则
<div class="quote">'(.+?/)'</div>PHP匹配代码
$contents = <<<EOT <article> <div class="quote">'引用/'</div> </article> EOT; if (preg_match('/<div class="quote">'(.+?)/'</div>/', $contents, $match)) { var_dump($match); }
注意: 上面的正则写到PHP代码中的时候,以下字符进行了转义:
1. ' 单引号
2. / 定界符
3. 转义字符,这是个比较特殊的字符
实现思路
要实现一个可用的代码生成,无非就是要把上面提到的特殊字符给转义了;
本想要用正则再对正则的字符串转义,最后发现不太靠谱,越写越复杂;
记起之前看过的redis conf分析相关的代码之后,遂选择逐字判断字符,并对字符转义,效果不错;注意优先级!
public function escape($value) { $chars = str_split($value); $len = count($chars); $result = ''; for ($i = 0; $i < $len; $i++) { if ($chars[$i] === '' && $i < $len - 1) { // 转义字符的判断优先级最高,可以避免 ' 正则的重复转义 $i++; // 跳过后面一个字符 if ($chars[$i] === '') { $result .= '\'; } else { $result .= '' . $chars[$i]; } } else if ($chars[$i] === ''') { // 单引号,php字符串边界 $result .= '''; } else if ($chars[$i] === '/') { // / php正则定界符 $result .= '/'; } else { $result .= $chars[$i]; } } return $result; }
