Как получить среднее значение строки с помощью Regexp в JS?

Мне нужно получить все, кроме первых 6 цифр и последних 4 цифр номера карты без специальных символов, что представляет собой строку, которая может быть следующей:

4500 1234 5678 7654 Или 4500-1234-5678-7654

Итак, мне нужно получить: 345678

До сих пор мне удавалось получить обратные значения, используя это:

^(\d[\- ]?){6}|[\- ]|(\d[\- ]?){4}$

Примечание. Я использую match() вместо replace() из-за бизнес-варианта использования в Nodejs.

ОБНОВЛЯТЬ: Спасибо всем за вашу помощь! На самом деле это должно быть в одной функции, если это возможно. Кроме того, длина кредитной карты варьируется от 13 до 18 цифр, что делает проблематичным полагаться на ее длину или положение для получения среднего значения.

Используйте регулярное выражение, чтобы удалить все, кроме цифр, затем используйте substr()

Barmar 13.12.2020 18:39

Вы не можете сделать это с помощью одного регулярного выражения.

Barmar 13.12.2020 18:39
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
848
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать вторую группу (\d{4}[ -]+\d{2})(\d{2}[ -]*\d{4})

Смотрите https://regex101.com/r/CFoh7m/1

Это будет включать пунктуацию в результат.

Barmar 13.12.2020 18:53

Спасибо, это было близко! Но дело в том, что длина карты может быть от 13 до 18 цифр, и тогда будет захвачена только ее часть. Также, как указал @Barmar, это будет включать пунктуацию.

Nahuel Candia 13.12.2020 18:58
Ответ принят как подходящий

Вам нужно сделать это в два этапа. Во-первых, удалите все нецифры с заменой регулярного выражения. Затем используйте substring(), чтобы получить нужную подстроку.

function middle_digits(cardnum) {
  let nondigits = cardnum.replace(/\D/g, '');
  return nondigits.substring(6, nondigits.length-4);
}
console.info(middle_digits('4500 1234 5678 7654'));
console.info(middle_digits('4500-1234-5678-7654'))

С помощью slice вы можете передать отрицательное значение endIndex, и функция станет такой: return cardnum.replace(/\D/g, '').slice(6, -4);

blex 13.12.2020 18:51

Это все еще два шага, думал, что это однострочник.

Barmar 13.12.2020 18:56

Я думаю, что требование сопоставлять числа, исключая заполнители (пробелы и тире), как указано, невозможно с одним регулярным выражением. Вы можете сопоставить несколько групп, а затем объединить их. Или вы можете сопоставить требуемый диапазон, а затем отфильтровать наполнители. вот последний подход:

const input = [
  '4500 1234 5678 7654',
  '4500-1234-5678-9012',
  '1234-5678-9012-3',
  '1234-5678-9012-3456-78'
];
const regex = /(?<=^(\d(?:[^\d]?)){6})((?:\d[^\d]?){3,})(?=(?:\d[^\d]?){4}$)/;
input.forEach(str => {
  let matched = str.match(regex);
  let cleaned = matched[0].replace(/[^\d]/g, '');
  console.info(str);
  console.info('=> matched: ' +matched);
  console.info('=> cleaned: ' +cleaned);
});

Выход:

4500 1234 5678 7654
=> matched: 34 5678 ,4,34 5678 
=> cleaned: 345678
4500-1234-5678-9012
=> matched: 34-5678-,4,34-5678-
=> cleaned: 345678
1234-5678-9012-3
=> matched: 78-9,1,78-9
=> cleaned: 789
1234-5678-9012-3456-78
=> matched: 78-9012-34,1,78-9012-34
=> cleaned: 78901234

Объяснение:

  • (?<=^(\d(?:[^\d]?)){6}) - положительное ретроспективное сканирование от начала до 6 номеров, за каждым из которых следует необязательный заполнитель
  • ((?:\d[^\d]?){3,}) - группа захвата, ожидайте 3+ числа, за каждым из которых следует необязательный наполнитель
  • (?=(?:\d[^\d]?){4}$) - положительное предварительное сканирование более 4 чисел, за каждым из которых следует необязательный заполнитель, до конца строки

Другие вопросы по теме