Как будет выглядеть регулярное выражения для проверки условия "Строка содержит маленькие латинские буквы, большие латинские буквы и цифры (выполнение всех трех условий сразу)." Также интересует быстродействие регулярных выражений. Это быстро? Сильно быстрее, чем посимвольная проверка? Заранее спасибо!
Ответ
Могу предложить такую регулярку:
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])
(?= ... ) — это zero-width positive lookahead assertion, то есть проверка, что строка в впереди удовлетворяет паттерну, при этом проверка не "съедает" символы при проверке, то есть после проверки возвращается на изначальную позицию. Скорее всего, это не самый оптимальный подход: вряд ли движок оптимизирует выражение.
При желании можно написать и выражение попроще:
^((?[a-z])|(?[A-Z])|(?
Или оптимальнее:
^(?>(?:(?[a-z])|(?[A-Z])|(?
Если вы охотитесь за производительностью, и какой-то алгоритм тривиально решается без регулярных выражений, то не используйте регулярные выражения. Они заведомо не будут быстрее.
RE: ReinRaus
Фига себе в джаве тормозной стандартный регекс. :)
Перевёл один-в-один в дотнет (плюс оптимизировал вторую регулярку: там был один лишний захват и, как следствие, баг в реализации от @ReinRaus, возникший при замене именованных групп на индексные):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace RegexPasswordPerf
{
class Program
{
static void Main (string[] args)
{
const int Loops = 30000;
const string Text = "AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8";
//const string Text = "AaluhfDnaoufbicbIHBDIHBKJXNdCJKfB1";
var regexes = new Dictionary
foreach (var entry in regexes) {
var regex = new Regex(entry.Value, RegexOptions.Compiled);
bool isCorrect = false;
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < Loops; i++)
isCorrect = regex.IsMatch(Text);
sw.Stop();
Console.WriteLine("{0}\t{1}\t{2}", entry.Key, sw.ElapsedMilliseconds, isCorrect);
}
}
}
}
Результат:
Discord 1 3378 True
Discord 2 2518 True
ReinRaus 1 738 True
ReinRaus 2 721 True
Если строку сделать больше похожей на пароль, то есть короче в несколько раз, то разрыв будет раза в два-три, а не три-четыре:
Discord 1 1247 True
Discord 2 1037 True
ReinRaus 1 650 True
ReinRaus 2 383 True
Подозреваю, что дотнетовый регекс проседает по производительности из-за того, что сохраняет абсолютно все совпадения. Если посмотреть содержимое результата:
string s = string.Join("
", m.Groups
.Cast
То можно увидеть это:
0: AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8AaluhfDnaoufbicbIHBDIHBKJXNdCJKfBCNCNX5BCHBAHIBAVIsdniuhuygvD6w489bgtvdihfcbsigdbcsihcgfisyg8
1021: a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g, a, l, u, h, f, n, a, o, u, f, b, i, c, b, d, f, s, d, n, i, u, h, u, y, g, v, w, b, g, t, v, d, i, h, f, c, b, s, i, g, d, b, c, s, i, h, c, g, f, i, s, y, g
990: A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D, A, D, I, H, B, D, I, H, B, K, J, X, N, C, J, K, B, C, N, C, N, X, B, C, H, B, A, H, I, B, A, V, I, D
1022: 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8, 5, 6, 4, 8, 9, 8
Это удобно, но не лучшим образом сказывается на производительности — особенно если соревноваться с регулярками, которые все совпадения не сохраняют. Для полного удовлетворения любопытства надо будет найти плюсовые или шарповые регексы, которые построены ради скорости, а не удобства. Если память не изменяет, регулярки из boost по умолчанию такой фигнёй не занимаются, но есть опция для компиляции.
Комментариев нет:
Отправить комментарий