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);

もっと効率的にできますか?または、正規表現を使用できますか? どちらがより効率的ですか?

4

2 に答える 2

1

プレーン文字列の一致は通常、正規表現の一致よりも高速です。私はそれをシンプルに保ち、次のようなことをします:

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

リストが常に「;」で始まるように手配できる場合 最初のエントリの検索は特別なケースではなくなり、ロジックを簡素化できます。

リストが大きくなり、これらの検索を大量に実行し、速度が本当に重要になる場合は、アドレスのリストを作成するときに、各プレフィックスをある種のハッシュまたはツリーに追加できます。これらのデータ構造の検索は、文字列の一致よりも高速である必要があります。

于 2012-04-17T05:51:15.727 に答える
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);
于 2012-04-17T07:52:29.350 に答える