十进制精度的动态正则表达式无法工作

时间:2018-03-19 14:16:09

标签: javascript regex

我有以下硬编码的RegEx表达式,用于小数精度&规模,有效(在另一个项目中):

// This would be a Decimal(2,3)
var regex = /\d{0,2}(\.\d{1,3})?$/;
var result = regex.test(text);

但是,我不想硬编码多种变体。而且,有趣的是,以下失败......但我不知道为什么。

我"思考"串联可能(某种程度上)影响"测试"

  • 我在这里做错了什么?

示例:

var validationRules = {
    decimal: {
        hasPrecision: function (precision, scale, text) {

            var regex = new RegExp('\d{0,' + precision + '}(\.\d{1,' + scale + '})?$'); 
            var result = regex.test(text);

            // result is ALWAYS true ????
            alert(result);
            alert(regex);
        }
    }
};

FAILING SAMPLE-SNIPPET:



$(document).ready(function () {

            var validationRules = {
                decimal: {
                    hasPrecision: function (precision, scale, text) {
                        
                        var regex = new RegExp('\d{0,' + precision + '}(\.\d{1,' + scale + '})?$'); 
                        var result = regex.test(text);

                        alert(result);
                        alert(regex);
                    }
                }
            };

            var masks = {
                decimal: function (e) {

                    // TODO: get Kendo MaskedTextBox to run RegEx
                    var regex = new RegExp("^([0-9\.])$");
                    var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);

                    if (!regex.test(key)) {
                        event.preventDefault();
                        return false;
                    }
                }
            };

            var button = $('.btn');
            var textbox = $('.txt');

            textbox.on('keypress', masks.decimal);
            button.on('click', function () {
                var text = textbox.val();

                validationRules.decimal.hasPrecision(2, 3, text);
            });
        });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="1111" class="txt">
<input type="button" class="btn" value="Run it">
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

始终在构建动态字符串时查看结果。在你的情况下,你正在构建它,并假设它正在变成你想要的REGEX模式。

您实际构建的是,例如:

d{0,2}(.d{1,3})?$

为什么呢?因为通过构造函数构建的REGEX模式(与文字相对)构建为字符串 - 并且字符串\被解释为转义字符。

然而,你需要这些反斜杠来保持你的模式,所以你需要双重逃避。实际上,您需要转义转义符,以便保留最后一个转义符。

var regex = new RegExp('\\d{0,' + precision + '}(\\.\\d{1,' + scale + '})?$');

这将导致相当于您的硬编码模式,假设 precisionscale包含您认为他们所做的整数。检查一下。 (例如,如果它们包含浮动,则会破坏您的模式。)

至于你的误报,这可能是由于缺少一个起始锚指令,即^

/\d{0,2}(\.\d{1,3})?$/.test("1234"); //true
/^\d{0,2}(\.\d{1,3})?$/.test("1234"); //false, note ^