作者:林子木 wolinxuebin
转载请保留:http://blog.csdn.net/wolinxuebin
由于还是码农新人,所以还未开始正式的编写大的工程代码,所以老员工给了我一个去年写的大的PHP工程的工程代码,先看下。抱着必须扫清每个死角的心里,下午碰到了
shtmlspecialchars()函数,网上一查挺多人都在用的,但不是PHP自带的,而是莫比较官方的写的。但是这里面的正则表达式着实让我纠结了一方,不讲废话了,切入正题。
function shtmlspecialchars($string) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = shtmlspecialchars($val);
}
} else {
$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
}
return $string;
}
以上就是shtmlspecialchars()函数的定义,其他的不讲,就讲这句让很多人揪心的
$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
这里先介绍下这个函数的作用:
html中可能出现的四种特殊字符进行转义,分别是
&转&
"转"
<转<
>转<(ps:这个后面的分号";"是连在一起的,一个整体,不是作者为了分隔用的)
这与PHP自带的htmlspecialchars()效果刚好相反。
那么一般人里面会用下面的代码实现这个函数所要实现的功能
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
但是 等一等!
问:等什么?不是已经完成了这个功能了?
答:错,大错,特错了,你这叫宁可枉杀3000,不放过一个,不人道的呀。
问:哪里错了?
答:情况下面的内容!
如果仅仅用上面的函数,那么会将 html特殊字符和unicode编码都破坏掉这可不是我们要的结果,具体字符表见文章后面的 附件。
有人观察了字符表的所有数据,最后得出下面的结论:
1、html特殊字符都是由&#开头后面加3-5个数字或者&#开头加一个字符和2-5个字符或数字组成的字符串
2、unicode编码是以&#开头后面加4个16进制数字组成的字符串。
根据第一条,我们应该写出正则表达式:&#/d{3,5}|[a-zA-Z][a-zA-Z0-9]{2,5};(ps:这个也是自带分号";"的)
根据第二条,可以得出&#[a-fA-F0-9]{4}; (ps:因为16进制是从0-f)
又由于前面的操作已经把&替换成了&所以讲上面两条整合下就出了下面的
/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/
问题1:
有人问,是不是可以写成下面的样子
/&#(((\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/
把井号提出来,当然可以,不过如果你要这样写,后面的再提,有些下改动。
我们把第一步操作
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
结果写成$string
那么反替换我们就可以简略的写成
preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',$string)
这里,前面的正则表达式已经很清楚了,但是作者又后面的&\\1搞晕了,什么意思呀?
经查证\1代表正则表达式的第一个括号内的内容。
自己写了一个测试
<?php
$string = 'x10p';
$string1 = preg_replace('/(x)([0-9]+)p/', '&\\1',$string);
$string2 = preg_replace('/x([0-9]+)p/', '&\\1',$string);
echo $string1;
echo '<br />';
echo $string2;
?>
输出的结果分别是
&x 第一括号内的是 x
&10 第一括号内的是10
preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',$string)
结果就是仅仅把$amp;替换为&而后面的保留不变。
到这可以解决上面的问题1,是否可以把#拿出来,如果你吧#拿出来的话,那么就是说会将&#都用&替换,然后后面的你得写'&#\\1',这样就可以,不过是不是感觉
多此一举了?是的!
参考文献:
【1】 http://blog.csdn.net/wolinxuebin/article/details/7604194 《php正则表达式详解》
【2】http://www.jb51.net/onlineread/htmlchar.htm HTML字符表
【3】http://deerchao.net/tutorials/regex/regex.htm 30分钟正则表达式入门
【4】http://topic.csdn.net/u/20100426/15/391a9a98-a457-451a-84d3-92d8f60ff0c0.html 关于uchome函数里面的shtmlspecilachars的功能 【5】http://s.yanghao.org/program/viewdetail.php?i=8324
附录:
html 字符表
特殊符号 | 命名实体 | 十进制编码 | 特殊符号 | 命名实体 | 十进制编码 | 特殊符号 | 命名实体 | 十进制编码 |
Α | Α | Α | Β | Β | Β | Γ | Γ | Γ |
Δ | Δ | Δ | Ε | Ε | Ε | Ζ | Ζ | Ζ |
Η | Η | Η | Θ | Θ | Θ | Ι | Ι | Ι |
Κ | Κ | Κ | Λ | Λ | Λ | Μ | Μ | Μ |
Ν | Ν | Ν | Ξ | Ξ | Ξ | Ο | Ο | Ο |
Π | Π | Π | Ρ | Ρ | Ρ | Σ | Σ | Σ |
Τ | Τ | Τ | Υ | Υ | Υ | Φ | Φ | Φ |
Χ | Χ | Χ | Ψ | Ψ | Ψ | Ω | Ω | Ω |
α | α | α | β | β | β | γ | γ | γ |
δ | δ | δ | ε | ε | ε | ζ | ζ | ζ |
η | η | η | θ | θ | θ | ι | ι | ι |
κ | κ | κ | λ | λ | λ | μ | μ | μ |
ν | ν | ν | ξ | ξ | ξ | ο | ο | ο |
π | π | π | ρ | ρ | ρ | ς | ς | ς |
σ | σ | σ | τ | τ | τ | υ | υ | υ |
φ | φ | φ | χ | χ | χ | ψ | ψ | ψ |
ω | ω | ω | ϑ | ϑ | ϑ | ϒ | ϒ | ϒ |
ϖ | ϖ | ϖ | • | • | • | … | … | … |
′ | ′ | ′ | ″ | ″ | ″ | ‾ | ‾ | ‾ |
⁄ | ⁄ | ⁄ | ℘ | ℘ | ℘ | ℑ | ℑ | ℑ |
ℜ | ℜ | ℜ | ™ | ™ | ™ | ℵ | ℵ | ℵ |
← | ← | ← | ↑ | ↑ | ↑ | → | → | → |
↓ | ↓ | ↓ | ↔ | ↔ | ↔ | ↵ | ↵ | ↵ |
⇐ | ⇐ | ⇐ | ⇑ | ⇑ | ⇑ | ⇒ | ⇒ | ⇒ |
⇓ | ⇓ | ⇓ | ⇔ | ⇔ | ⇔ | ∀ | ∀ | ∀ |
∂ | ∂ | ∂ | ∃ | ∃ | ∃ | ∅ | ∅ | ∅ |
∇ | ∇ | ∇ | ∈ | ∈ | ∈ | ∉ | ∉ | ∉ |
∋ | ∋ | ∋ | ∏ | ∏ | ∏ | ∑ | ∑ | − |
− | − | − | ∗ | ∗ | ∗ | √ | √ | √ |
∝ | ∝ | ∝ | ∞ | ∞ | ∞ | ∠ | ∠ | ∠ |
∧ | ∧ | ⊥ | ∨ | ∨ | ⊦ | ∩ | ∩ | ∩ |
∪ | ∪ | ∪ | ∫ | ∫ | ∫ | ∴ | ∴ | ∴ |
∼ | ∼ | ∼ | ≅ | ≅ | ≅ | ≈ | ≈ | ≅ |
≠ | ≠ | ≠ | ≡ | ≡ | ≡ | ≤ | ≤ | ≤ |
≥ | ≥ | ≥ | ⊂ | ⊂ | ⊂ | ⊃ | ⊃ | ⊃ |
⊄ | ⊄ | ⊄ | ⊆ | ⊆ | ⊆ | ⊇ | ⊇ | ⊇ |
⊕ | ⊕ | ⊕ | ⊗ | ⊗ | ⊗ | ⊥ | ⊥ | ⊥ |
⋅ | ⋅ | ⋅ | ⌈ | ⌈ | ⌈ | ⌉ | ⌉ | ⌉ |
⌊ | ⌊ | ⌊ | ⌋ | ⌋ | ⌋ | ◊ | ◊ | ◊ |
♠ | ♠ | ♠ | ♣ | ♣ | ♣ | ♥ | ♥ | ♥ |
♦ | ♦ | ♦ | |   | ¡ | ¡ | ¡ | |
¢ | ¢ | ¢ | £ | £ | £ | ¤ | ¤ | ¤ |
¥ | ¥ | ¥ | ¦ | ¦ | ¦ | § | § | § |
¨ | ¨ | ¨ | © | © | © | ª | ª | ª |
« | « | « | ¬ | ¬ | ¬ | ­ | ­ | |
® | ® | ® | ¯ | ¯ | ¯ | ° | ° | ° |
± | ± | ± | ² | ² | ² | ³ | ³ | ³ |
´ | ´ | ´ | µ | µ | µ | " | " | " |
< | < | < | > | > | > | ' | ' |