Какой самый эффективный способ проверить, является ли строка частью большей строки?
У меня есть строка, которая формируется путем объединения 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);