LINUX.ORG.RU

Нетривиальная регулярка

 ,


0

1

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

★★★★★

Ответ на: комментарий от atrus

/.*[0-9]+.*[A-Z]+.*|.*[A-Z]+.*[0-9]+.*/

P.S.: А тут было ещё требование на проверку [a-z]. Способом выше можно родить условие вроде /.*[0-9]+.*[A-Z]+.*[a-z]+.*/, но потребуется ещё 135 символов, чтобы дописать это условие.

gedisdone ★★★ ()

Можно. Как в первом ответе предлагалось, удобнее проверять, что строка не подходит под твои требования: (^([0-9A-Z]*|[0-9a-z]*|[A-Za-z]*)$|[^0-9A-Za-z]). Если сматчилось, то либо есть какой-то символ, отличный от букв и цифр, или же не хватает символа в какой-то из трех категорий. Но лучше сделать это в несколько проверок. Код получится более понятный в результате.

TeopeTuK ★★★ ()
Ответ на: комментарий от jtad

Регулярка выглядит как дрова.

Если не нравится for, есть же алгоритмы. Будет и понятно и коротко, вместо нечитаемых регулярок.

Вот можно вместо for использовать: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/every

fsb4000 ★★★ ()
Ответ на: комментарий от fsb4000

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

jtad ()
Ответ на: комментарий от jtad

Но на работе если ты владеешь регекспами, то ты профи

Конечно, нет.

Я бы сделал с помощью алгоритма. Не стоит делать код запутанней и тормознее без необходимости.

решается в одну строчку, и без регулярки.

allSymbolsCorrect = [...s].every(ch => isNum(ch) || isBigLetter(ch) || isSmallLetter(ch));

Потом разбор результатов, притом мы точно знаем причину почему строка не подошла, а не как с регуляркой, лишь подошла или нет:

if (!allSymbolsCorrect) {
  console.log("string has wrong letter");
}
else if (!hasNum) {
  console.log("string doesn't have number");
}
else if (!hasBigLetter) {
  console.log("string doesn't have big letter");
}
else if (!hasSmallLetter) {
  console.log("string doesn't have small letter");
}
else {
  console.log("Everything is fine");
}
fsb4000 ★★★ ()
Ответ на: комментарий от jtad

регекспы это мощный инструмент

В рамках стандартов он не очень мощный. За рамками стандартов он просто вредный.

Но на работе если ты владеешь регекспами, то ты профи.

Если ты работаешь Perl-программистом или вообще не программистом. Для какого-нибудь условного закупщика умение использовать BRE/ERE - действительно здорово.

anonymous ()
Ответ на: комментарий от anonymous

ну расскажите мне плиз что это за стандарты за рамками которого они вредны? Понятие «тут слишком просто для регулярок, можно и циклом» слишком размыто. Это может в случае если регулярка слишком сложна для понимания, а задача не очень сложная, то согласен

jtad ()
Ответ на: комментарий от jtad

ну расскажите мне плиз что это за стандарты

Аббревиатуры BRE и ERE в моём комментарии.

если регулярка слишком сложна для понимания

Проблема ещё в том, что при написании обычно всё понятно, а потом через полгода, когда надо немного поправить, ты вспоминаешь это высказывание Завински :)

anonymous ()
Ответ на: комментарий от fsb4000

конечно нет

конечно да

решается в одну строчку, и без регулярки.

allSymbolsCorrect = [...s].every(ch => isNum(ch) || isBigLetter(ch) || isSmallLetter(ch));

)) и ЭТО решение лучше регулярки? я заморачиватся не буду, но решал по методу Nervous в свое время. Выглядит в разы понятнее

jtad ()
Последнее исправление: jtad (всего исправлений: 1)
Ответ на: комментарий от anonymous

при написании обычно всё понятно, а потом через полгода, когда надо немного поправить

Для этого в нормальных языках регулярки можно делать многострочными и песать к нужным кускам комменты.

Nervous ★★★★ ()

Проход по всей строки один раз точно будет быстрее регулярки которую тут можно придумать.

Ну и да… У нас была проблема, мы решили её с помощью regex. Теперь у нас две проблемы :)

kardapoltsev ★★★ ()

можно и регуляркой, но дешевле обычными условиями и циклами, тем более что у тебя ограниченный латиницей алфавит, а с сортировкой так вообще детский лепет.

anonymous ()
Ответ на: комментарий от atrus

А для чего?

Твоя задача от «простой проверки пароля на сложность» отличается только тем, что тебя, согласно озвученному условию, устроит строка от трёх символов длиной. Множественные решения с разъяснениями использующие один регексп гуглятся на раз.

frob ★★★★★ ()
Ответ на: комментарий от jtad

регекспы это мощный инструмент. Если хочешь заменить на цикл, то велком. Но

Лукахед и лукбихайнд делают регулярку зависящей от входных данных по времени выполнения. Что вообще-то довольно непрофессионально.

Я уже молчу, что цикл лучше и нечего тут. Заверни в функцию с соответствующим именем и всё.

anonymous ()
Ответ на: комментарий от atrus

Там комбинация 2 условий, а результат уж такой то хоть вешайся. С тремя будет в 4 раза хуже.

Твоя задача нормального решения на регекспе не имеет. Технически - комбинация перестановок (a, b, c). Можно. Только прочесть это будет не реально. И еще думать как прописать чтобы не DDoS-или.

Будет намного быстрее и проще сделать 1 проход со сканом charCodeAt().

Vit ★★★★★ ()
Ответ на: комментарий от atrus
var s = 'sperma'
undefined
/^[a-z\d]+$/i.test(s) && /[A-Z]/.test(s) && /[a-z]/.test(s) && /\d/.test(s)
false
var s = 'ozon671games'
undefined
/^[a-z\d]+$/i.test(s) && /[A-Z]/.test(s) && /[a-z]/.test(s) && /\d/.test(s)
false
var s = 'Mamoep1488'
undefined
/^[a-z\d]+$/i.test(s) && /[A-Z]/.test(s) && /[a-z]/.test(s) && /\d/.test(s)
true

Без регулярок:

function isValidUsername(s) {
  let digits = false
  let upper = false
  let lower = false
  for (let c of s) {
    if (c >= '0' && c <= '9') {
      digits = true
    } else if (c >= 'a' && c <= 'z') {
      lower = true
    } else if (c >= 'A' && c <= 'Z') {
      upper = true
    } else {
      return false
    }
  }
  return (digits && lower && upper)
}
tz4678 ()
Последнее исправление: tz4678 (всего исправлений: 2)