LINUX.ORG.RU

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

 ,


0

1

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

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

Это даст то, что других символов нет. А как ещё гарантировать что точно есть хотя бы по одной A-Z, a-z и 0-9...

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

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

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

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

Там ещё условие, что только эти символы. .* не вписывается.

kardapoltsev ★★★★★
()

А зачем тут вообще регулярка?

Решается за один проход по каждому символу, простым циклом for…

fsb4000 ★★★★★
()

any*type1+any*type2+any*type3+any*|any*type1+any*type3+any*type2+any*|... и так все возможные перестановки. type1 == [0-9], any == [0-9a-zA-Z].

kardapoltsev ★★★★★
()

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

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

Код получится более понятный в результате

Я бы больше беспокоился об эффективности. А все перестановки можно красиво и элегантно сгенерировать.

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

Решается за один проход по каждому символу, простым циклом for…

+1

no-such-file ★★★★★
()

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

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

циклом можно все сделать… Но регексп в этом случае выглядит как яйцо фаберже по сравнению с кучей дров сделанных топором

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

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

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

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

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

Some people, when confronted with a problem, think «I know, I’ll use regular expressions.» Now they have two problems.

anonymous
()

Три простые и понятные регулярки сделают хорошо любому, кто будет читать код или добавлять/изменять эти требования.

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

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

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

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

Хтмл тоже парсишь регекспами?

anonymous
()
Ответ на: комментарий от 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
()
Ответ на: комментарий от anonymous

отсортиртируй строку

регуляркой

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

А для чего?

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

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

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

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

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

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

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

Лолшто? %)

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

Лолшто? %)

Гхэ-эр-эр-эр. Прости, я просто отрыгнул в ответ.

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

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

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

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

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

Понятно... Что ж, напишем. Я просто с JS не очень дружу, по этому стараюсь следовать правилу: Чем меньше кода написано - тем лучше. :)

atrus ★★★★★
() автор топика
Ответ на: комментарий от 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)
Ответ на: комментарий от tz4678

Спасибо. Я уж правда совсем нагло код за меня писать не просил. Всё-таки мы на ЛОРе, а не на stackoverflow... ;-)

atrus ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.