2012-04-19 143 views
-2

我想排除一些內部IP地址和一些內部IP地址格式查看站點中的某些標識和鏈接。我有多個IP地址範圍(示例如下)。是否有可能編寫一個正則表達式,可以匹配下面列表中的所有IP地址使用JavaScript?Javascript多個正則表達式模式

10.X.X.X 
12.122.X.X 
12.211.X.X 
64.X.X.X 
64.23.X.X 
74.23.211.92 
and 10 more 
+4

是的,這是可能的:'。*'匹配所有這些......你的問題是模糊的 - 你想要任何種類的IPv4地址ss來匹配?如果不是,匹配的規則是什麼?這是一個真正的'X'或者你是否認爲這是「任何」的佔位符?什麼是「10個以上」的IP地址? – 2012-04-19 21:04:00

+0

我需要匹配15個IP地址格式(注意:「格式」有些是確切的IP地址,有些需要匹配10.X.X.X格式)。我提供了幾個樣本。 – neelmeg 2012-04-19 21:10:03

回答

3

報價期間,與更換X的\d+,並用管道將它們連接在一起的所有:

var allowedIPpatterns = [ 
    "10.X.X.X", 
    "12.122.X.X", 
    "12.211.X.X", 
    "64.X.X.X", 
    "64.23.X.X", 
    "74.23.211.92" //, etc. 
]; 

var allowedRegexStr = '^(?:' + 
    allowedIPpatterns. 
    join('|'). 
    replace(/\./g, '\\.'). 
    replace(/X/g, '\d+') + 
    ')$'; 

var allowedRegexp = new RegExp(allowedRegexStr); 

然後你所有的設置:

'10.1.2.3'.match(allowedRegexp) // => ['10.1.2.3'] 
'100.1.2.3'.match(allowedRegexp) // => null 

如果輸入甚至可能不是一個合法的IP地址在所有的,你可以改變'\d+'的東西,只匹配有效的字節值,如'(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])'

工作原理:

首先,我們必須把個別IP模式到匹配他們的意圖正則表達式。對於「形式'12 .122.X.X「的所有IP」一個正則表達式是這樣的:

^12\.122\.\d+\.\d+$

  • ^意味着比賽已經在字符串的開頭開始;否則,112.122.X.X IPs也會匹配。
  • 12 etc:數字匹配
  • \.:正則表達式中的句點與任何字符匹配;我們需要文字時間,所以我們在前面加了一個反斜槓。
  • \d:簡寫爲[0-9];匹配任何數字。
  • +:表示「1或更多」 - 在這種情況下爲1位或更多位。
  • $:與^類似,這意味着匹配必須在字符串末尾結束。

所以,我們把IP模式到這樣的正則表達式。對於個人模式,你可以使用這樣的代碼:

var regexStr = `^` + ipXpattern. 
    replace(/\./g, '\\.'). 
    replace(/X/g, '\\d+') + 
    `$`; 

剛剛與\.X s的\d+替換所有. S和貼在兩端的^$

在正則表達式,所述交替this|that匹配,要麼thisthat匹配任何東西。因此,如果我們將列表轉換爲形式爲re1|re2|re3|...|relast的單個正則表達式,我們可以一次檢查所有IP的匹配。

然後我們可以做一些重構,使正則表達式匹配的工作更輕鬆;在這種情況下,因爲所有的正則表達式都會有^...$,所以我們可以將這些約束從單個正則表達式中移除,並將它們放在整個事物上:^(10\.\d+\.\d+\.\d+|12\.122\.\d+\.\d+|...)$。括號保持^不僅僅是第一種模式的一部分,並且僅僅是最後一種模式的一部分。但是由於圓括號捕捉的是小組,所以我們不需要捕捉任何東西,所以我將它們替換爲非分組版本(?: .. )

在這種情況下,我們可以做的全局搜索和替換在巨大的字符串,而不是一次單獨對每個模式。所以結果是上面的代碼:

var allowedRegexStr = '^(?:' + 
    allowedIPpatterns. 
    join('|'). 
    replace(/\./g, '\\.'). 
    replace(/X/g, '\d+') + 
    ')$'; 

這仍然只是一個字符串;我們必須把它變成一個實際的RegExp對象做匹配:

var allowedRegexp = new RegExp(allowedRegexStr); 

書面,這並不能過濾掉非法IP地址 - 例如,10.1234.5678.9012將匹配的第一圖案。如果你想在單個字節值限制在十進制範圍爲0-255,可以使用更復雜的正則表達式比\d+,像這樣:

(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]) 

這意味着「任何一個或兩個數字,或‘1’隨後是任意兩位數字,或'2'後面跟隨任意'0'到'4'後跟任意數字,或者'25'後跟'0'到'5'中的任何一個。

這使得整個字符串的正則表達式看起來更笨拙:

^(?:10\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\.(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]).(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])|12\.122\.... 

,但你不必看它,只是比賽反對。 :)

+0

你能解釋一下這行代碼的作用嗎? '^(?:'+ allowedIPs.join('|')。replace(/\./ g,'\\。')。replace(/ X/g,'[^。] +')+ ' )$' 我看到它按照我的要求工作,非常好奇它是如何工作的。 – neelmeg 2012-04-20 14:55:56

+0

它將允許的IP數組轉換爲正則表達式,以匹配其中的任何一個。 .join('|')將數組組合爲一個由'|'分隔的大字符串。 (例如「10.X.X.X | 12.122.X.X | ...」)。 '|'在正則表達式中表示「或」。 .replace(/\./ g,'\\。')用反斜槓引用所有的句點;正則表達式中的句點匹配任何字符,但我們只想匹配文字句點。 .replace(/ X/g,'[^。] +')用'[^。] +'代替所有'X',這在正則表達式中意味着「1個或更多非週期」。 把它放在^(...)$之間意味着整個字符串必須匹配;否則「110.2.3.4」將匹配「10.x.x.x」。 – 2012-04-20 15:21:54

0

/^(X|\d{1,3})(\.(X|\d{1,3})){3}$/應該這樣做。

+0

你能不能解釋一下這個正則表達式呢? – neelmeg 2012-04-19 21:11:40

+0

它匹配格式爲X.X.X.X的字符串,其中X可以是1-3個數字或大寫X.它的肉就是這個子表達式'\。(X | \ d {1,3})'。它匹配一個句點,後面跟1-3或者X. – cebarrett 2012-04-19 21:20:52

+0

這是一個很好的正則表達式語法參考:http://www.regular-expressions.info/reference.html – cebarrett 2012-04-19 21:22:52

0

如果你實際上並不需要相匹配的「X」字符,你可以這樣做:

\b(?:\d{1,3}\.){3}\d{1,3}\b 

否則我會使用所提供的解決方案cebarrett。

1

你能做到這一點的正則表達式,但它不會是漂亮的,特別是因爲JavaScript的甚至不支持正則表達式冗長的,這意味着它必須是正則表達式的一個堆積如山的行沒有任何意見。此外,正則表達式不適合匹配數字範圍。我懷疑有更好的工具來處理這個問題。

嗯,好吧,這裏去(爲您提供的樣本):

var myregexp = /\b(?:74\.23\.211\.92|(?:12\.(?:122|211)|64\.23)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])|(?:10|64)\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))\b/g; 

作爲一個詳細的( 「讀取」)的正則表達式:

\b     # start of number 
(?:    # Either match... 
74\.23\.211\.92 # an explicit address 
|     # or 
(?:    # an address that starts with 
    12\.(?:122|211) # 12.122 or 12.211 
|     # or 
    64\.23   # 64.23 
) 
\.    # . 
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot 
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255 
|     # or 
(?:10|64)   # match 10 or 64 
\.    # . 
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot 
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\. # followed by 0..255 and a dot 
(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]) # followed by 0..255 
) 
\b     # end of number 
0

我不能完全肯定的你想在這裏實現什麼(不看其他人要麼是)。

但是,如果它的驗證,那麼這裏就是驗證不使用正則表達式的IP地址解決方案。首先,在點處分割輸入字符串。然後在數字上使用parseInt,確保它不高於255。

function ipValidator(ipAddress) { 
var ipSegments = ipAddress.split('.'); 
for(var i=0;i<ipSegments.length;i++) 
    { 
     if(parseInt(ipSegments[i]) > 255){ 
      return 'fail'; 
     } 
    } 
return 'match'; 
} 

運行以下命令返回 '匹配':

document.write(ipValidator('10.255.255.125')); 

而這會返回 '失敗':

document.write(ipValidator('10.255.256.125')); 

下面是一個的jsfiddle著名版本的一些例子,http://jsfiddle.net/VGp2p/2/