2016年7月27日 星期三

正規表示式的 lookahead 和 lookbehind

起因:
要將email除了前三和後三字元屏蔽
ex.
TestEmail@google.com => Tes**************com

打開sublime,把 TestEmail@google.com 貼上去,用Find功能開始嘗試正則去匹配,只要用正則選取到除了前三和後三中間的字後,再用 preg_replace( '/regex/u', '*', $email )  去取代掉

先選取第三個字以後的字串
先說結論:
(?<=\S{3}).
如何實現的?
http://stackoverflow.com/questions/2973436/regex-lookahead-lookbehind-and-atomic-groups
使用了 positive lookbehind
Look ahead positive (?=)
Find expression A where expression B follows:
找有B接在後面的A
A(?=B)
ex.
TestEmail@google.com  // 正則搜尋 g(?=o)

Look ahead negative (?!)
Find expression A where expression B does not follow:
找沒有B接在後面的A
A(?!B)
ex.
TestEmail@google.com // 正則搜尋 g(?!o)

Look behind positive (?<=)
Find expression A where expression B precedes:
找有B接在前面的A
(?<=B)A
ex.
TestEmail@google.com // 正則搜尋 (?<=g)o

Look behind negative (?<!)
Find expression A where expression B precedes:
找沒有B接在前面的A
(?<=B)A
ex.
TestEmail@google.com // 正則搜尋 (?<!g)o

所以 (?<=\S{3}). 是 找三個( {3} )非空字元( \S )接在前面的任意字元( . ),就會選到
TestEmail@google.com

選取倒數地三個字以前的字串
先說結論:
.(?=.*\S{3})

使用了 Look ahead positive 
.(?=.*\S{3}) 是 找有 三個( {3} )非空字元( \S ) 接在後面的任意字元

把兩個合起來
(?<=\S{3}).(?=.*\S{3})

所以PHP 這樣寫
preg_replace('/(?<=\S{3}).(?=.*\S{3})/u','*','TestEmail@Google.com')  // Tes**************com

/u 是什麼意思?
http://stackoverflow.com/questions/12896985/regex-modifier-u-in-javascript
The /u modifier in PHP is for unicode support. This modifier is not supported in JavaScript.
/u 修飾符( modifier )是PHP的 unicode支持,javascript不支持

vim搜尋時如何做到 Look ahead negative

找沒有B接在後面的A
A(?!B)
在vim中是不作用的
https://stackoverflow.com/questions/21148467/is-there-a-way-to-do-negative-lookahead-in-vim-regex
https://stackoverflow.com/questions/34548988/match-a-pattern-not-followed-by-a-sub-pattern-in-vim
/\vA(B)@!
\v -  啟動very magic 解析模式
@! -  inverts the atom (B), so that the pattern matches when B is absent
@! -  倒轉原子(B),所以將會匹配沒有B的情況

:h \@! 可直接看vim解釋








沒有留言:

張貼留言