【问题标题】:What is the most efficient way to check if a string is part of a bigger string?检查字符串是否是更大字符串的一部分的最有效方法是什么?
【发布时间】:2012-04-17 04:42:43
【问题描述】:

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

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

【问题讨论】:

  • 在查找127.25 时,是否要匹配127.255.1.43 之类的字符串? (我选择了一个比你的问题中的127.272.1.43 更理智的例子)......
  • @TimPietzcker 抱歉有人编辑并删除了 27 之后的点。我已将其添加回来

标签: regex string ip-address apache-stringutils


【解决方案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 建议使用更智能的数据结构。字符串并不意味着支持快速前缀搜索。如果你构建一个 IP 地址树,那么这个问题就变得微不足道了。 (如果建议使用普通的旧字符串例程而不是正则表达式,我会再给一个 +1,但我只能投票一次。;)
  • 这也会找到部分匹配。例如,如果您正在寻找 127.25,它也会找到 127.255.1.43,这可能不是 Darshan 所期望的。
  • @TimPietzcker nope.. 因为我们正在搜索“127.25”。
  • @Ah,好的,当我写评论时,点不在那里。
【解决方案2】:

假设您只关心整个 IP 地址匹配,并假设您在查找 127.25 时不希望 127.255.1.43 匹配,那么

(?<=^|;)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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2022-01-15
    • 2020-01-19
    • 2018-01-03
    相关资源
    最近更新 更多