Мне нужно получить все, кроме первых 6 цифр и последних 4 цифр номера карты без специальных символов, что представляет собой строку, которая может быть следующей:
4500 1234 5678 7654 Или 4500-1234-5678-7654
Итак, мне нужно получить: 345678
До сих пор мне удавалось получить обратные значения, используя это:
^(\d[\- ]?){6}|[\- ]|(\d[\- ]?){4}$
Примечание. Я использую match() вместо replace() из-за бизнес-варианта использования в Nodejs.
ОБНОВЛЯТЬ: Спасибо всем за вашу помощь! На самом деле это должно быть в одной функции, если это возможно. Кроме того, длина кредитной карты варьируется от 13 до 18 цифр, что делает проблематичным полагаться на ее длину или положение для получения среднего значения.
Вы не можете сделать это с помощью одного регулярного выражения.
Вы можете использовать вторую группу (\d{4}[ -]+\d{2})(\d{2}[ -]*\d{4})
Смотрите https://regex101.com/r/CFoh7m/1
Это будет включать пунктуацию в результат.
Спасибо, это было близко! Но дело в том, что длина карты может быть от 13 до 18 цифр, и тогда будет захвачена только ее часть. Также, как указал @Barmar, это будет включать пунктуацию.
Вам нужно сделать это в два этапа. Во-первых, удалите все нецифры с заменой регулярного выражения. Затем используйте 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);
Это все еще два шага, думал, что это однострочник.
Я думаю, что требование сопоставлять числа, исключая заполнители (пробелы и тире), как указано, невозможно с одним регулярным выражением. Вы можете сопоставить несколько групп, а затем объединить их. Или вы можете сопоставить требуемый диапазон, а затем отфильтровать наполнители. вот последний подход:
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 чисел, за каждым из которых следует необязательный заполнитель, до конца строки
Используйте регулярное выражение, чтобы удалить все, кроме цифр, затем используйте
substr()