首頁  >  文章  >  後端開發  >  javascript - 關於正規表示式的一個問題

javascript - 關於正規表示式的一個問題

WBOY
WBOY原創
2016-08-04 09:18:591051瀏覽

問題: 有字串:「python php ruby​​ javascript jsonp perhapsphpisoutdated」
對於該字串,使用純正則取得 所有帶p 但是不能包含ph 的單字

輸出數組 [ 'python', 'javascript', 'jsonp' ]

這個問題想了比較久,也沒思路
我的解法是

<code>var result = str.match(/\b\w*(?=p)\w*\b/g)
                .filter((value)=>!/.*(?=ph)/.test(value))
var result2 = str.match(  /\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g  ) 
console.log(result2)</code>

但是不符合純正則的要求

群裡有大牛給了這麼一個答案

<code>/\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g </code>

完美運行

但是我看不懂,希望有大牛能幫我解讀

回覆內容:

問題: 有字串:「python php ruby​​ javascript jsonp perhapsphpisoutdated」
對於該字串,使用純正則取得 所有帶p 但是不能包含ph 的單字

輸出數組 [ 'python', 'javascript', 'jsonp' ]

這個問題想了比較久,也沒思路
我的解法是

<code>var result = str.match(/\b\w*(?=p)\w*\b/g)
                .filter((value)=>!/.*(?=ph)/.test(value))
var result2 = str.match(  /\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g  ) 
console.log(result2)</code>

但是不符合純正則的要求

群裡有大牛給了這麼一個答案

<code>/\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g </code>

完美運行

但是我看不懂,希望有大牛能幫我解讀

<code>var str = 'python php ruby javascript jsonp perhapsphpisoutdated';
var reg = /\b(\w*(p[^h\s](?!ph))\w*)\b/g;
str.match(reg);
// => ["python", "javascript", "perhapsphpisoutdated"]</code>
  • b為邊界字符,範圍為wW之間的字符。

  • ()標識的是子表達式。

  • (?!)標識的是反向先行斷言,和子表達式不同是先行斷言並不會被記錄。

  • [^]標識的是取不符合條件的集合

所以上面的正則意思為取邊界之間的含有‘p’但是後面緊跟的字符串不是‘h’或‘空格’,同時後面也不含有‘ph’的字符串

b((?!ph|s).)*((p[^hs]((?!ph|s).)*)|p)b/g
b 是邊界字元

所以每一個字對應的配對是:
((?!ph|s).)*((p[^hs]((?!ph|s).)*)|p)

把這個表達式拆成三個部分:

  1. ((?!ph|s).)*

  2. (p[^hs]((?!ph|s).)*)

  3. p

表達式裡出現最多的是 ((?!ph|s).)* 讓我們來分析一下

《javascript權威指南》裡講: (?!p)零寬度負向先行斷言,表示接下來的字符不與 p 匹配

這裡的 零寬度 是指 它本身不佔用匹配
可能這一點比較難理解,舉個例子,比如:

計算"1234".match(/((?!34).)*/)的值

  1. 第一次(?!34)之前沒有東西、忽略,只對.進行匹配,匹配到"1",字符串剩餘"234"

  2. "234"進行匹配,測試"23"是否匹配?!裡的"34",結果不匹配,繼續進行,"23""34",結果不匹配,繼續進行,"23"🟎"沒有被消耗,接下來的.配對到

    "2"
  3. ,
  4. "34"進行匹配,由於"34"匹配?!裡的

    "34"
  5. ,匹配終止

整個表達式的匹配結果是"12"

結論:/((?!p).)*/形式的表達式匹配到的字串是

p
之前的部分

    這裡再來看之前的三個表達式:
  1. ((?!ph|s).)*
  2. (p[^hs]((?!ph|s).)*)
  3. p
  • 第一個表達式表示匹配單字中

    "ph"
  • 或 空格之前的盡量長的字元
  • 第二個表達式匹配單字中"p" 及之後的字符,要求"p" 之後的第一個字符不能為"h",並且同樣要求不匹配到

    "ph"
  • 第三個表達式匹配單獨的"p" 字符,因為之前的匹配中最短能匹配到的形式是

    p[^hs]
  • ,至少為兩個字符,而單個"p"字符樓主的要求但未被包括在內,所以單獨匹配

梳理一下就會發現,上面的匹配的三個表達式都不匹配 "ph", 但其中一定會有

"p"🎜,完全符合題主的要求🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn