检查字符串是否是更大字符串的一部分的最有效方法是什么?

时间:2012-04-17 04:42:43

标签: regex string ip-address apache-stringutils

我有一个由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);

效率更高吗?或者我可以使用正则表达式吗?哪一个更有效率?

2 个答案:

答案 0 :(得分:1)

普通字符串匹配通常比正则表达式匹配更快。我会保持简单并做这样的事情:

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

如果您可以安排列表始终以';'开头然后搜索第一个条目将不再是一个特例,逻辑可以简化。

如果列表很大并且您将要进行大量这些搜索并且速度非常重要,那么也许您可以在构建地址列表时将每个前缀添加到某种哈希或树。这些数据结构中的查找应该比字符串匹配更快。

答案 1 :(得分: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);