Есть ли способ упростить сопоставление регулярных выражений символов? - PullRequest
2 голосов
/ 25 февраля 2020

Я пытаюсь создать регулярное выражение ECMAScript (JavaScript), чтобы проверить надежность моего пароля на основе следующих критериев:

    Characters Used          Password Strength Length
   ABC  abc  123  #$&      WEAK  ...
1   x                      1-5   ...   
2        x                 1-5
3             x            1-7
4                  x       1-5
5   x    x                 1-4   
6   x         x            1-4
7   x              x       1-4
8        x    x            1-4 
9        x         x       1-4       
10            x    x       1-4     
11  x    x    x            1-4           
12  x    x         x       1-3   
13  x        x     x       1-4           
14      x    x     x       1-4  
15  x   x    x     x       1-3     

Таким образом, пароли типа 2, ABCD, 0123456, abCd, aA# и др. c. должен быть отмечен как слабый. Пароли, которые длиннее для указанной комбинации 012345678, aA1#, et c. не должен.

Это мой очень длинный атм регулярного выражения (который в основном склеивается через группы в соответствии с таблицей выше):

/^(([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})|([a-z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})|([A-Z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})|([a-zA-Z0-9]{1,4})|([a-z]{1,5})|([A-Z]{1,5})|([0-9]{1,7})|([&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,5}))$/

Соответствует строкам (над таблицей): 12

/([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})/

Соответствует строкам: 14, 9

/([a-z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})/

Соответствует строкам: 13, 10, 7

/([A-Z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})/

Соответствует строкам: 11, 8, 6, 5

/([a-zA-Z0-9]{1,4})/

Соответствует строкам: 2

/([a-z]{1,5})/

Соответствует строкам: 1

/([A-Z]{1,5})/

Соответствует строкам: 3

/([0-9]{1,7})/

Соответствует строкам: 4

/([&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,5})/

Есть ли способ повторно использовать специальные символы, которые я указал внутри [] [&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.], поэтому мне не нужно писать их все внутри каждой группы?

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Есть ли способ повторно использовать специальные символы, которые я указал внутри [] ... поэтому мне не нужно писать их все внутри каждой группы?

Не с литерал регулярного выражения, нет.

Вы можете сделать это с помощью конструктора RegExp. Вы можете смягчить тот факт, что она хочет строку, используя String.raw, поэтому вам не нужно беспокоиться об избежании обратной косой черты:

const chars = String.raw`[the chars]`;
const rex = new RegExp(String.raw`^...${chars}...${chars}...$`);

Вы можете пойти дальше, создав специальную функцию тега c для вот так (это пример из главы 10 моей новой книги; подробности см. в моем профиле):

const createRegex = (template, ...values) => {
    // Build the source from the raw text segments and values
    const source = String.raw(template, ...values);
    // Check it's in /expr/flags form
    const match = /^\/(.+)\/([a-z]*)$/.exec(source);
    if (!match) {
        throw new Error("Invalid regular expression");
    }
    // Get the expression and flags, create
    const [, expr, flags = ""] = match;
    return new RegExp(expr, flags);
};

Тогда:

const chars = String.raw`[the chars]`;
const rex = createRegex`/^...${chars}...${chars}...$/`;
0 голосов
/ 25 февраля 2020

Я не уверен, какой движок регулярных выражений вы используете. Однако, если это Perl или Ruby, вы можете использовать подпрограммы для достижения этого в значительной степени . Подпрограммы - это повторяющиеся шаблоны в регулярном выражении.

Возможно, вы знаете о обратных ссылках. Однако подпрограммы отличаются от обратных ссылок. В случае обратной ссылки содержимое захваченной группы сопоставляется, а не шаблон. Однако в случае подпрограммы сопоставление с образцом повторяется.

Давайте рассмотрим пример.

  • Тестовая строка: abcd-defg
  • Regex в Ruby: /(?<dd>[a-z]+)-\g<dd>/. Совпадение будет успешным.
  • Часть \g<dd> - это вызов подпрограммы в Ruby группе с именем dd. (\g<group_name> - это Ruby стиль регулярного выражения. Для используемого вами двигателя он может отличаться.)

Подробнее здесь:


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

  • [A-Z] как A
  • [a-z] как a
  • [0-9] как n
  • специальный символ установлен как s (Не уверен, правильно ли я понял этот шаблон.)

Затем шаблон для 12 /([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})/ становится

/((\g<A>|\g<a>|\g<s>)){1,3})/

То есть A OR a OR s repeated 1-3 times.

И шаблон для 11, 8, 6, 5 /([a-zA-Z0-9]{1,4})/ становится

/((\g<a>|\g<A>|\g<n>)){1,4})/

То есть, a OR A OR n repeated 1-4 times.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...