由於還是碼農新人,所以還未開始正式的編寫大的工程代碼,所以老員工給了我一個去年寫的大的PHP工程的工程代碼,先看下。抱著必須掃清每個死角的心裡,下午碰到了
shtmlspecialchars()函數,網上一查挺多人都在用的,但不是PHP內建的,而是莫比較官方的寫的。但是這裡面的Regex著實讓我糾結了一方,不講廢話了,切入正題。
[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()函數的定義,其他的不講,就講這句讓很多人揪心的
[php]
$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()效果剛好相反。
那麼一般人裡面會用下面的代碼實現這個函數所要實現的功能
[php]
str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
但是等一等!
問:等什嗎?不是已經完成了這個功能了?
答:錯,大錯,特錯了,你這叫寧可枉殺3000,不放過一個,不人道的呀。
問:哪裡錯了?
答:情況下面的內容!
如果僅僅用上面的函數,那麼會將html特殊字元和unicode編碼都破壞掉這可不是我們要的結果,具體字元表見文章後面的附件。
有人觀察了字元表的所有資料,最後得出下面的結論:
1、html特殊字元都是由&#開頭後面加3-5個數字或者&#開頭加一個字元和2-5個字元或數字組成的字串
2、unicode編碼是以&#開頭後面加4個16進位數字組成的字串。
根據第一條,我們應該寫出Regex:&#/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});)/
把井號提出來,當然可以,不過如果你要這樣寫,後面的再提,有些下改動。
我們把第一步操作
[php]
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)
這裡,前面的Regex已經很清楚了,但是作者又後面的&\\1搞暈了,什麼意思呀?
經查證\1代表Regex的第一個括弧內的內容。
自己寫了一個測試
[php]
$string = 'x10p';
$string1 = preg_replace('/(x)([0-9]+)p/', '&\\1',$string);
$string2 = preg_replace('/x([0-9]+)p/', '&\\1',$string);
echo $string1;
echo '
';
echo $string2;
?>
輸出的結果分別是
&x 第一括弧內的是 x
&10 第一括弧內的是10
[php]
preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',$string)
結果就是僅僅把$amp;替換為&而後面的保留不變。
到這可以解決上面的問題1,是否可以把#拿出來,如果你吧#拿出來的話,那麼就是說會將&#都用&替換,然後後面的你得寫'&#\\1',這樣就可以,不過是不是感覺
多此一舉了?是的!
附錄:
html 字元表
特殊符號 具名實體 十進位編碼 特殊符號 具名實體 十進位編碼 特殊符號 具名實體 十進位編碼
Α Α Α Β Β Β Γ Γ Γ
Δ Δ Δ Ε Ε Ε Ζ Ζ Ζ
Η Η Η Θ Θ Θ Ι Ι Ι
Κ Κ Κ Λ Λ Λ Μ Μ Μ
Ν Ν Ν Ξ Ξ Ξ Ο Ο Ο
Π Π Π Ρ Ρ Ρ Σ Σ Σ
Τ Τ Τ Υ Υ Υ Φ Φ Φ
Χ Χ Χ Ψ Ψ Ψ Ω Ω Ω
α α α β β β γ γ γ
δ δ δ ε ε ε ζ ζ ζ
η η η θ θ θ ι ι ι
κ κ κ λ λ λ μ μ μ
ν ν ν ξ ξ ξ ο ο ο
π π π ρ ρ ρ ς ς ς
σ σ σ τ τ τ υ υ υ
φ φ φ χ χ χ ψ ψ ψ
ω ω ω ϑ ϑ ϑ ϒ ϒ ϒ
ϖ ϖ ϖ • • • … … …
′ ′ ′ ″ ″ ″ ‾ ‾ ‾
⁄ ⁄ ⁄ ℘ ℘ ℘ ℑ ℑ ℑ
ℜ ℜ ℜ ™ ™ ™ ℵ ℵ ℵ
← ← ← ↑ ↑ ↑ → → →
↓ ↓ ↓ ↔ ↔ ↔ ↵ ↵ ↵
⇐ ⇐ ⇐ ⇑ ⇑ ⇑ ⇒ ⇒ ⇒
⇓ ⇓ ⇓ ⇔ ⇔ ⇔ ∀ ∀ ∀
∂ ∂ ∂ ∃ ∃ ∃ ∅ ∅ ∅
∇ ∇ ∇ ∈ ∈ ∈ ∉ ∉ ∉
∋ ∋ ∋ ∏ ∏ ∏ ∑ ∑ −
− − − ∗ ∗ ∗ √ √ √
∝ ∝ ∝ ∞ ∞ ∞ ∠ ∠ ∠
∧ ∧ ⊥ ∨ ∨ ⊦ ∩ ∩ ∩
∪ ∪ ∪ ∫ ∫ ∫ ∴ ∴ ∴
∼ ∼ ∼ ≅ ≅ ≅ ≈ ≈ ≅
≠ ≠ ≠ ≡ ≡ ≡ ≤ ≤ ≤
≥ ≥ ≥ ⊂ ⊂ ⊂ ⊃ ⊃ ⊃
⊄ ⊄ ⊄ ⊆ ⊆ ⊆ ⊇ ⊇ ⊇
⊕ ⊕ ⊕ ⊗ ⊗ ⊗ ⊥ ⊥ ⊥
⋅ ⋅ ⋅ ⌈ ⌈ ⌈ ⌉ ⌉ ⌉
⌊ ⌊ ⌊ ⌋ ⌋ ⌋ ◊ ◊ ◊
♠ ♠ ♠ ♣ ♣ ♣ ♥ ♥ ♥
♦ ♦ ♦ ¡ ¡ ¡
¢ ¢ ¢ £ £ £ ¤ ¤ ¤
¥ ¥ ¥ ¦ ¦ ¦ § § §
¨ ¨ ¨ © © © ª ª ª
« « « ¬ ¬ ¬
® ® ® ¯ ¯ ¯ ° ° °
± ± ± ² ² ² ³ ³ ³
´ ´ ´ µ µ µ " " "
< < < > > > ' '
作者:wolinxuebin
http://www.bkjia.com/PHPjc/478078.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/478078.htmlTechArticle由於還是碼農新人,所以還未開始正式的編寫大的工程代碼,所以老員工給了我一個去年寫的大的PHP工程的工程代碼,先看下。抱著必須掃...