Какой самый эффективный способ проверить, является ли строка частью большей строки?

У меня есть строка, которая формируется путем объединения 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 ответа

Решение

Совпадения в простых строках обычно выполняются быстрее, чем в регулярных выражениях. Я бы сделал это просто и сделал бы что-то вроде этого:

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

Если вы можете сделать так, чтобы список всегда начинался с ';' тогда поиск первой записи больше не будет частным случаем, и логика может быть упрощена.

Если список будет большим, и вы собираетесь выполнять множество таких поисков, и скорость действительно имеет значение, то, возможно, вы могли бы добавить каждый префикс к какому-либо хешу или дереву при построении списка адресов. Поиск в этих структурах данных должен быть быстрее совпадений строк.

Предполагая, что вы заботитесь только о полных совпадениях 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);
Другие вопросы по тегам