Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как проверить комбинацию символов в строке? (https://javascript.ru/forum/misc/78635-kak-proverit-kombinaciyu-simvolov-v-stroke.html)

CryNet 12.10.2019 16:57

Как проверить комбинацию символов в строке?
 
Нужно реализовать функцию
function verif(<тут переданная строка>) {
    // тело функции
}

которая принимает строки вида:
  • verif("#АБВГДЕЁЖЗИЙ(КЛМНОПРС)ТУФХЦЧШЩЬЫЪЭЮЯ#");
    
  • verif("#абвгдеёжзийклмнопрстуфхцчшщьыъэюя#");
    
  • verif("*АБВГДЕЁЖЗИЙКЛМН(ОПРСТУФХЦЧШЩЬЫЪЭЮЯ*");
    
И вернёт true если в строке есть комбинация из символов ( и ), * и *, # и #
Но вернёт false если внутри комбинации встретиться символ из другой комбинации, типа:
  • verif("*АБВГДЕЁЖЗИЙКЛМН(ОПРСТУФХЦЧШЩЬЫЪЭЮЯ*");
    
    - должно вернуть false, потому что внутри комбинации * и * есть символ (
При этом
  • verif("#АБВГДЕЁЖЗИЙ(КЛМНОПРС)ТУФХЦЧШЩЬЫЪЭЮЯ#");
    
    вернёт true, потому что пройдёт проверку на комбинацию ( и )

рони 12.10.2019 18:17

CryNet,
вариант ...
function verif(str) {
    const reg = /(^[*#])(?![*#()а-яё]*?\1$)|[(](?![*#()а-яё]*?[)])/gi;//
    return !reg.test(str)
}
console.log(verif("#АБВГДЕЁЖЗИЙ(КЛМНОПРС)ТУФХЦЧШЩЬЫЪЭЮЯ#")); //true
console.log(verif("*АБВГДЕЁЖЗИЙКЛМН(ОПРСТУФХЦЧШЩЬЫЪЭЮЯ*")); //false
console.log(verif("#абвгдеёжзийклмнопрстуфхцчшщьыъэюя#")); //true

laimas 12.10.2019 18:34

рони, не всему отвечает, например:

console.log(verif("#АБВГДЕЁЖЗИЙ(КЛМ ОПРС)ТУФХЦЧШЩЬ)ЫЪЭЮЯ#")) будет true, но должно быть false.

рони 12.10.2019 19:29

laimas,
:) если так?
function verif(str) {
    const reg = /(^[*#])[()а-яё]*\1$/i;
    const rg = /[(][^()]*?[)]/;
    const r = /[()]/;
    if(!reg.test(str)) return false;
    for (; rg.test(str); ) {rg.lastIndex = 0; str = str.replace(rg, ''); rg.lastIndex = 0;}
    return !r.test(str)
}
console.log(verif("#АБВГДЕЁЖЗИЙ(КЛМНОПРС)ТУФХЦЧШЩЬЫЪЭЮЯ#")); //true
console.log(verif("*АБВГДЕЁЖЗИЙКЛМН(ОПРСТУФХЦЧШЩЬЫЪЭЮЯ*")); //false
console.log(verif("#абвгдеёжзийклмнопрстуфхцчшщьыъэюя#")); //true
console.log(verif("#АБВГДЕЁЖЗИЙ(КЛМНОПРС)ТУФХЦЧШЩЬЫ)ЪЭЮЯ#")); //false

laimas 12.10.2019 19:57

Ну если скобки в скобках недопустимы, то тоже не пойдет.

laimas 12.10.2019 20:33

рони, видимо лучше не напрягать разборкой по различным выражениям, а получить массив посимвольный, проверить крайние, затем срез 1, -1 обойти циклом, проверяя - если допустимый символ (не # или *), продолжаем, иначе если ")", а открывающая скобка не запоминалась, то ошибка, иначе очистить открывающую скобку. Если "(" и следующий индекс не символ разрешенный, то ошибка, иначе запомнить открывающую скобку.

рони 12.10.2019 20:39

laimas,
подожду, может уже достаточно.

laimas 12.10.2019 20:41

Цитата:

Сообщение от рони
может уже достаточно

Может быть :), но странное если такие условия и при этом можно "#АБВГДЕЁЖ(ЗИЙ(КЛМНОПРС)ТУФ) ХЦЧШЩЬЫЪЭЮЯ#"

CryNet 12.10.2019 21:02

Цитата:

Сообщение от рони (Сообщение 513871)
CryNet,

function verif(str) {
    const reg = /(^[*#])(?![*#()а-яё]*?\1$)|[(](?![*#()а-яё]*?[)])/gi;

Блин. Сложно. Если нужно будет добавить новые символы или условие, то я запутаюсь. Но всё равно спасибо :)

Alexandroppolus 12.10.2019 21:53

Я не очень понял, что требуется. Это разновидность задачи о проверке скобочной целостности с тремя видами скобок?

CryNet 12.10.2019 23:19

Цитата:

Сообщение от Alexandroppolus (Сообщение 513883)
Я не очень понял, что требуется. Это разновидность задачи о проверке скобочной целостности с тремя видами скобок?

она самая. Даже не разновидность :) Просто хотелось выйти за рамки самой задачи

рони 12.10.2019 23:26

CryNet,
https://javascript.ru/forum/css-html...teki-v-js.html

Alexandroppolus 13.10.2019 07:09

Цитата:

Сообщение от CryNet (Сообщение 513886)
она самая. Даже не разновидность :) Просто хотелось выйти за рамки самой задачи

Но символы * и # могут быть открывашками и закрывашками, эта роль, видимо, чередуется?
То есть '****' аналогична '()()', но не '(())', так?

CryNet 13.10.2019 13:23

так :)

Alexandroppolus 13.10.2019 18:24

var config = {
  '(': ')',
  '{': '}',
  '[': ']',
  '<': '>',
  '*': '*',
  '#': '#'
};

function checkParentheses(config, str) {
  if (!str || !config) { return true; }
  var stack = [];
  var closeChars = Object.create(null);
  Object.keys(config).forEach(function(open) {
    var close = config[open];
    closeChars[close] = open !== close;
  });
  for (var i = 0; i < str.length; ++i) {
    var char = str.charAt(i);
    var isClose = closeChars[char];
    var closeForChar = config[char];
    if (isClose) {
      if (!stack.length || stack.pop() !== char) {
        return false;
      }
    } else if (closeForChar) {
      stack.push(closeForChar);
    }
    if (char === closeForChar) {
      closeChars[char] = !closeChars[char];
    }
  }
  return !stack.length;
}

alert(checkParentheses(config, '(aaa*hjhg*)'));
alert(checkParentheses(config, '(aaa*hjhg)'));


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


Часовой пояс GMT +3, время: 21:52.