更正丹麦手机号码的正则表达式

Correct RegEx for danish mobile number

我找到了以下正则表达式 ( ^(((?+45)?)?)(\s?\d{2}\s?\d{2}\s?\ d{2}\s?\d{2})$ ) 和 ( /(?:45\s)?(?:\d{2}\s){3}\d{2}/ )验证丹麦手机号码.但是,它与以下也是有效手机号码的输入不匹配:

4511760574, 004511760574

只有以下号码之一的手机号码才有效

a) 它的任意 8 位数字 b) 以 45、+45 或 0045 开头的 8 位数字 c) 排除 45、+45 或 0045 后的前两位数字应如下所示(标有蓝色的部分):

来源:https://en.wikipedia.org/wiki/Telephone_numbers_in_Denmark

PS: 如果 (c) 是最新的,我不是 100% 有信心。但是,如果 (c)

发生任何更新,我可以通过调整轻松更改正则表达式,我将不胜感激

以下是仅与问题相关的代码片段:

****HTML****
<input type="text" class="form-control num-only-with-plus rounded-0" id="phone"
                            placeholder="Telefonnummer" required maxlength="12">
<div id="phone-number-feedback" class="invalid-feedback">Invalid Number</div>

****JS****
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"
    integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ=="
    crossorigin="anonymous"></script>

<script type="text/javascript">

function validateMobileNumber(phone) {
        const pattern = /(?:45\s)?(?:\d{2}\s){3}\d{2}/g;
        return pattern.test(String(phone).toLowerCase());
    }

//Allow only digit and '+' sign on the input field
$('.num-only-with-plus').keypress(function (e) {
    if (e.key != '+' && e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
            return false;
        }
$('#phone').keyup(_.debounce(function () {
            const phone = $(this)
            if (validateMobileNumber(phone.val())) {
                phone.toggleValid()
                $('#submit_btn').prop('disabled', false)                
            } else {
                phone.toggleInvalid();
                $('#phone-number-feedback').text("Tjek venligst mobilnummeret igen. Er det okay?")
                $('#submit_btn').prop('disabled', true)
            }
        }, 500));
</script>


请帮忙!

让我们通过构建模式的要求:第一个和第二个...

a) its either 8 digits

b) OR 8 digits starting with either 45, +45 or 0045

...比较直接,可以这样表达:

(?:(?:00|\+)?45)?\d{8}

这个表达式的核心是 \d{8} 部分(意思是 8 位数字)。在它之前的是 'double-optional' 部分,大致意思是“...可选地前面有 45,它本身可以有选择地前面有 00 或 [=16=” ] 符号'。 ?: 印记用于防止正则表达式引擎捕获那些字符组的内容,从而使模式更快、更少 memory-consuming。

到目前为止一切顺利,但我们如何表达第三个要求,即 \d{8} 部分开头有一组特定的数字?虽然可以修改 'heart part' 以包含这些子句,但还有一个更易于维护的替代方案 - 正面前瞻:

(?=2|3[01]|4[012]|4911|5[0-3]|6[01]|[78]1|9[123])

仅当检查字符串中的特定位置后跟 2、或 30-31、或 40-42、或 4911、或 50-53、或 60-61 时,才满足模式的这一部分,或 71,或 81,或 91-93 - 就像该 wiki 页面中所写的那样。如果有任何变化,无需触及正则表达式的任何其他部分即可轻松更新该部分。

所以最终的模式看起来像这样:

^(?:(?:00|\+)?45)?(?=2|3[01]|4[012]|4911|5[0-3]|6[01]|[78]1|9[123])\d{8}$

这里是 regex101 demo,您可以使用它来播放模式和示例字符串。