2012-04-17 81 views
1

我有一個由IP地址的串聯形成一個字符串,例如:什麼是檢查字符串是否是更大字符串的一部分的最有效方法?

"127.272.1.43;27.27.1.43;127.127.27.67;128.27.1.43;127.20.1.43;111.27.1.43;127.27.1.43;" 

當給定一個新的IP地址,我需要檢查,如果IP的前半部分是IP地址的一部分串。例如,如果"127.27.123.23"給予我需要找到如果任何字符串中的IP地址與"127.27"

開始我有下面的代碼,其中userIP = "127.27."

int i = StringUtils.indexOf(dbIPString, userIP); 
do { 
    if (i > 0) { 
     char ch = dbIPString.charAt(i - 1); 
     if (ch == ';') { 
      System.out.println("IP is present in db"); 
      break; 

     } else { 
      i = StringUtils.indexOf(dbIPString, userIP, i); 
     } 
    } else if (i == 0) { 
     System.out.println("IP is present in db"); 
     break; 
    } else { 

     System.out.println("IP is not present in db"); 
    } 
} while (i >= 0); 

它可以更有效?或者我可以使用正則表達式嗎?哪一個更有效?

+0

你要像'127.255.1.43'字符串匹配尋找'127.25'什麼時候? (我已經選擇了比你的問題中的'127.272.1.43'更爲理智的示例)... – 2012-04-17 07:39:42

+0

@TimPietzcker對不起有人編輯並刪除了後面的點27 ..我已將其添加回 – 2012-04-17 07:51:09

回答

1

普通字符串匹配通常比正則表達式匹配更快。我會保持簡單,並做這樣的事情:

if (StringUtils.startsWith(dbIPString, userIP)) { 
    ... // prefix is present 
} else if (StringUtils.indexOf(dbIPString, ";" + userIP) > 0) { 
    ... // prefix is present 
} else { 
    ... // prefix is not present 
} 

如果您可以安排列表總是以';'開頭,那麼搜索第一個條目將不再是特例,並且可以簡化邏輯。

如果列表將會很大,並且您將要執行大量這些搜索並且速度真的很重要,那麼也許您可以在構建地址列表時將每個前綴添加到某種散列或樹中。這些數據結構中的查找應該比字符串匹配更快。

+0

+1以表示使用更聰明的數據結構。字符串並不意味着支持快速前綴搜索。如果你建立一個IP地址樹,那麼這個問題就變得微不足道了。 (我會給出另一個+1用於提示使用普通的舊字符串例程,而不是正則表達式,但我只能調高一次;)) – 2012-04-17 07:12:38

+0

這也發現部分匹配。例如,如果你正在尋找'127.25',它也會發現'127.255.1.43',這可能不是Darshan所期望的。 – 2012-04-17 07:41:25

+0

@TimPietzcker nope ..因爲我們正在搜索「127.25」。 – 2012-04-17 07:47:51

0

假設你只關心整個IP地址匹配,並假設你不想127.255.1.43,當你正在尋找127.25,然後

(?<=^|;)127\.25\.\d+\.\d+ 

將是一個合適的正則表達式匹配。

在Java:

Pattern regex = Pattern.compile(
    "(?<=^|;)  # Assert position at the start of the string or after ;\n" + 
    Pattern.quote(userIP) + 
    "\\.\\d+\\.\\d+ # Match .nnn.nnn", 
    Pattern.COMMENTS); 
相關問題