Javascript Pangram Regex

Я пытаюсь написать РЕГЕКС для проверки на ПАНГРАММУ. Я могу сделать это традиционным способом, но не могу решить его для более чем 90% моих тестов с регулярным выражением.

Строка ввода

Вывод: правда || ложный

function isPangram(string){ 
   return ___________________.test(string) 
}

Результаты теста пока что.

6/10/([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z, \s]+)/i

6/10/[a-z]{1}/i

6/10 /[a-z]/i

6/10 /[a-z]+/i

9/10 /a?b?c?d?e?f?g?h?i?j?k?l?m?n?o?p?q?r?s?t?u?v?w?x?y?z/i только не удалось против abcdefghijklmopqrstuvwxyz

6/10 /[\w.]+/

Любая помощь или совет с благодарностью.

10 ответов

Решение

Это был бы правильный ответ на вызов:

function isPangram(string){ 
   return /(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f)(?=.*g)(?=.*h)(?=.*i)(?=.*j)(?=.*k)(?=.*l)(?=.*m)(?=.*n)(?=.*o)(?=.*p)(?=.*q)(?=.*r)(?=.*s)(?=.*t)(?=.*u)(?=.*v)(?=.*w)(?=.*x)(?=.*y)(?=.*z)./i.test(string) 
}

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

  1. Преобразовать строку в нижний регистр
  2. Используйте регулярные выражения, чтобы извлечь все уникальные алфавиты из строки
  3. Проверьте, нет ли уникальных алфавитов 26

Код:

function isPangram(string) {
    var regex = /([a-z])(?!.*\1)/g;
    return (string.match(regex) || []).length === 26;
}

Regex101

var regex = /([a-z])(?!.*\1)/g;

function check() {
  var val = document.getElementById('text').value.toLowerCase();

  alert(val.match(regex).length == 26);
}
<input type="text" id="text" />

<button onclick="check()">Check</button>

Однолинейное решение:

const isPangram = (string) => new Set(string.toLowerCase().match(/[a-z]/gi)).size === 26

Как одно регулярное выражение:

      /(?:(?=(.*?([a-z]))(?!.*\2))\1){26}/i

Проверьте это на regex101.

Разбивка:

      /
  (?:               // non-capturing group
    (?=             // look-ahead assertion

      (.*?([a-z]))  // match a letter, preceded by as few characters as possible
      (?!.*\2)      // assert that this letter does not appear in the remainder of the string
                    // (in aggregate, this will find the last occurrence of each letter)

    )\1             // actually match that group (this is done to prevent backtracking)
  ){26}             // match 26 times (once for each letter)
/i                  // match case-insensitively

Если используемый вами механизм регулярных выражений поддерживает атомарную группировку (например, PCRE), это можно записать несколько более кратко:

      /(?>.*?([a-z])(?!.*\1)){26}/i

regex101.

использование цикла for..of & включает:

      function isPangram(sentence) {
let lowerCased = sentence.toLowerCase();
for (let char of 'abcdefghijklmnopqrstuvwxyz') {
    if (!lowerCased.includes(char)) {
        return false;
     }
  }
 return true;
}

Учитывая строку, определите, является ли она панграммой. Верните True, если это так, и False, если нет. Не обращайте внимания на цифры и знаки препинания. [добавление нечувствительности к регистру на основе кода регулярного выражения, предоставленного @Tushar]

Добавляя к решению Тушара , я заметил, что их регулярное выражение соответствует только одному регистру в их коде; но в их HTML-файле было больше сценариев. С использованием[a-zA-Z]регулярное выражение для соответствия строчным и прописным буквам будет означать, что панграмма должна содержать 52 буквы. Итак, чтобы исправить это, мы все равно можем сделать его равным 26, переведя строку в нижний регистр перед ее проверкой, просто используя toLowerCaseметод.

Кроме того, я думал, что вы пришли из упражнения Pangram от Exercism , потому что вы упомянули, что было десять тестов и что лучшее решение не прошло. Я убедился, что это пройдет.

Код

      const isPangram = string =>
  (string.toLowerCase().match(/([a-z])(?!.*\1)/g) ?? []).length === 26;
  1. Преобразовать строку в нижний регистр
  2. Соответствие регулярному выражению
  3. Если совпадение ложное, вместо этого используйте пустой массив.
  4. Проверьте, равна ли длина 26, что соответствует панграмме.

Регулярное выражение

([a-z])(?!.*\1)

  1. Первая группа захвата совпадений для каждой буквы от a до z
  2. Вторая группа использует отрицательный просмотр вперед , чтобы определить, не соответствует ли какой-либо символ первой группе.

Также

Да, и кстати, я использовал нулевой оператор объединения (??). В принципе это но специально дляnullилиundefined

Вы можете думать об этом как!=против||и!==против??быть тем же самым; соответственно, первая проверка на ложность, а вторая проверка на строгое неравенство.

      function isPangram(input) {
  if(input.length < 26) {
    return false;
  }
  const letters = 'abcdefghijklmnopqrstuvwxyz';
  return Array.from(new Set(input.toLowerCase().split('').filter(i => i.trim()))).sort().join('') === letters;  
}

console.log(isPangram("The String is abcdefghijklumnopqrstvwxyz")); //true

      function isPangram(string){

  let lc = string.toLowerCase()
 let alphabet = "abcdefghijklmnopqrstuvwxyz"

   return alphabet.split("").filter(c => lc.indexOf(c) === -1).length === 0;
}
  1. Строчная строка
  2. Создайте строку с алфавитом
  3. разбить алфавит
  4. Использование filter () с мини-функцией, которая проверит, что в нем 0 ложных операторов (отфильтруйте его так, чтобы в новом массиве, создаваемом методом фильтрации, было 0 (ноль) ложных операторов (-1) ".lengeth === 0"гарантирует отсутствие ложных утверждений)
Другие вопросы по тегам