如何在 JS 中使用 Regexp 获取字符串的中间值?
How do I get the middle value of a string using Regexp in JS?
除了没有特殊字符的卡号的前 6 位和后 4 位之外,我需要获取所有内容,这是一个字符串,可以如下所示:
4500 1234 5678 7654
要么
4500-1234-5678-7654
所以我需要得到:345678
到目前为止,我能够使用以下方法得到反数值:
^(\d[\- ]?){6}|[\- ]|(\d[\- ]?){4}$
注意:由于 Nodejs 中的业务特定用例,我使用 match() 而不是 replace()。
更新:
谢谢大家到目前为止的帮助!如果可能的话,它实际上需要在一个函数中。此外,信用卡的长度从 13 到 18 位不等,这使得依赖其长度或位置来获取中间值存在问题。
可以用第二组(\d{4}[ -]+\d{2})(\d{2}[ -]*\d{4})
您需要分两步完成。首先,使用正则表达式替换删除所有非数字。然后使用 substring()
获取所需的子字符串。
function middle_digits(cardnum) {
let nondigits = cardnum.replace(/\D/g, '');
return nondigits.substring(6, nondigits.length-4);
}
console.log(middle_digits('4500 1234 5678 7654'));
console.log(middle_digits('4500-1234-5678-7654'))
我认为使用单个正则表达式无法满足所述的匹配不包括填充符(空格和破折号)的数字的要求。您可以匹配多个组,然后组合它们。或者,您可以匹配所需的范围,然后过滤掉填充物。这是后一种方法:
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.log(str);
console.log('=> matched: ' +matched);
console.log('=> 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 个数字,每个数字后跟可选的填充符,直到字符串结尾
除了没有特殊字符的卡号的前 6 位和后 4 位之外,我需要获取所有内容,这是一个字符串,可以如下所示:
4500 1234 5678 7654 要么 4500-1234-5678-7654
所以我需要得到:345678
到目前为止,我能够使用以下方法得到反数值:
^(\d[\- ]?){6}|[\- ]|(\d[\- ]?){4}$
注意:由于 Nodejs 中的业务特定用例,我使用 match() 而不是 replace()。
更新: 谢谢大家到目前为止的帮助!如果可能的话,它实际上需要在一个函数中。此外,信用卡的长度从 13 到 18 位不等,这使得依赖其长度或位置来获取中间值存在问题。
可以用第二组(\d{4}[ -]+\d{2})(\d{2}[ -]*\d{4})
您需要分两步完成。首先,使用正则表达式替换删除所有非数字。然后使用 substring()
获取所需的子字符串。
function middle_digits(cardnum) {
let nondigits = cardnum.replace(/\D/g, '');
return nondigits.substring(6, nondigits.length-4);
}
console.log(middle_digits('4500 1234 5678 7654'));
console.log(middle_digits('4500-1234-5678-7654'))
我认为使用单个正则表达式无法满足所述的匹配不包括填充符(空格和破折号)的数字的要求。您可以匹配多个组,然后组合它们。或者,您可以匹配所需的范围,然后过滤掉填充物。这是后一种方法:
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.log(str);
console.log('=> matched: ' +matched);
console.log('=> 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 个数字,每个数字后跟可选的填充符,直到字符串结尾