Chia sẽ anh em hàm validate mình viết

Chia sẽ anh em hàm validate mình viết cái này được cái  cái này gọn nhẹ sài được cho div không cần gắn vào form, có thể validate những nhóm đối tượng tách biệt nhau, theo class, id , attributes....

Để xử dụng cần gán thuộc tính required vào và các loại class int, date, datetim, dec , email..

var ThuY = {};
ThuY.Form = function (formId) {
    this.hasError = false;
    this.$element = $(formId);

    this.focusError = function () {
        var $input = this.$element.find(".has-error:first :input");
        if ($input.length === 0) return;
        $("html, body").animate({ scrollTop: $input.offset().top - 100 }, 250);
        $input.focus();
    };
     function getValue($el) {
        return $el.is('[type="checkbox"]')
            ? $el.prop("checked")
            : $el.is('[type="radio"]') ? !!$('[name="' + $el.attr("name") + '"]:checked').length : $el.val();
    }
    this.getError = function () {
        var formError = {};

        this.$element.find('input[required],textarea[required],select[required]').each(function (i, requiredField) {
            var $el = $(requiredField);
            var $type = $el.attr('type');

            var $message = $el.attr('reqired-message');
            if (isNotSet($message)) {
                $message = "Giá trị này phải nhập";
            }

            var $maxLength = $el.attr('data-max');
            var $minLength = $el.attr('data-min');
            var $pattern = $el.attr('data-pattern');
            var $value = getValue($el);

            if ($el.hasClass('int')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (typeof n == 'number' && /^-?\d+$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseInt($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseInt($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }
            } else if ($el.hasClass('dec')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^\d+.?\d*$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseFloat($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseFloat($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }

            } else if ($el.hasClass('email') || $type === 'email') {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/.test($value) === false) {
                    formError[$el.attr('name')] = "Email không đúng định dạng";
                }

            } else if ($el.hasClass('url') || $type === 'url') {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test($value) === false) {
                    formError[$el.attr('name')] = "Website không đúng định dạng";
                }
            } else if ($el.hasClass('date')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})[\/](\d{2})[\/](\d{4})$/.test($value) === false) {
                    //Check date 99/99/9999
                    formError[$el.attr('name')] = "Ngày tháng không đúng định dạng";
                }
            } else if ($el.hasClass('time')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                    //Check time 99:99
                } else if (/([01]\d|2[0-3]):([0-5]\d)/.test($value) === false) {
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if ($el.hasClass('datetime')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})$/.test($value) === false) {
                    //Check date time 99/99/9999 99:99
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if (isSet($pattern)) {

                if ($pattern.test($value) === false) {
                    formError[$el.attr('name')] = "Giá trị nhập vào không đúng định dạng";
                }
            } else {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (isSet($minLength)) {
                    if ($el.val().length < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if ($el.val().length > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự nhỏ hơn " + $maxLength;
                    }
                }
            }
            $el.bind('change', function () {
                formError[$(this).attr('name')] = null;
            });


        });

        if (!$.isEmptyObject(formError)) { this.hasError = true; }
        return formError;

    }
    this.isFloat = function (val) {
        var floatRegex = /^-?\d+(?:[.,]\d*?)?$/;
        if (!floatRegex.test(val)) return false;
        val = parseFloat(val);
        if (isNaN(val)) return false;
        return true;
    }

    this.isInt = function (val) {
        var intRegex = /^-?\d+$/;
        if (!intRegex.test(val))return false;
        var intVal = parseInt(val, 10);
        return parseFloat(val) === intVal && !isNaN(intVal);
    }
    this.resetForm = function () {
        this.$element.find("input, textarea, select").val("");
    }

    this.isEmpty = function (value, allowEmptyString) {
        function countProperty(obj) {
            var count = 0;
            for (var k in obj)
                obj.hasOwnProperty(k) && ++count;
            return count;
        }

        return value === false ||
            null === value ||
            isNaN(value) === false && 0 === parseInt(value, 10) ||
            "null" === value ||
            void 0 === value ||
            "undefined" === value ||
            (allowEmptyString ? false : "" === value) ||
            "object" == typeof value && 0 === countProperty(value) ||
            "object" == typeof value && 1 === countProperty(value) && "" === value[0] ||
            value instanceof jQuery && 0 === value.length;
    }
    this.loadItem = function () {
        var $item = {};
        this.$element.find('input,textarea,select')
            .each(function (i, item) {
                $item[$(item).attr('name')] = getValue($(item));
            });

        return $item;
    }
    this.item =  this.loadItem();
}

để xử dụng trong controller mình làm như sau

var form = new ThuY.Form("#formAddKhach");
$scope.formErrorAddKhach = form.getError();
if (form.hasError) {
    form.focusError();
    return;
}

html

<div class="col-md-3">
    <div class="form-group" data-ng-class="{'has-error' : formAddKhach.Ten.$invalid && formAddKhach.Ten.$dirty || formErrorAddKhach.Ten}">
        <label class="control-label" for="Ten">{{L('Ten')}} <span class="require">*</span></label>
        <div class="">
            <input class="form-control" id="Ten" name="Ten" ng-model="itemAddKhach.Ten" required reqired-message="Tên bắt buộc nhập." />
            <span class="help-block" ng-show="formAddKhach.Ten.$invalid  && formAddKhach.Ten.$dirty">Nhập {{L('Ten')}}</span>
            <span class="help-block" ng-if="formErrorAddKhach.Ten">{{formErrorAddKhach.Ten}}</span>
        </div>
    </div>
</div>

 

Một số phương thức của mảng trong Javascript

Để viết các ứng dụng với javascript thì việc vận dụng mảng là một điều hết sức cần thiết. Javascript cũng như các ngôn ngữ lập trình khác cũng có mảng và cách thức làm việc của mảng trong Javascript cũng tương tự, vấn đề cần quan tâm là các chức năng thao tác với mảng thì mỗi một ngôn ngữ lập trình đều viết sẵn một số hàm hoặc phương thức để thao tác, ý nghĩa của các hàm thì giống nhau chỉ khác ở cách khai báo và cách gọi tên hàm của từng ngôn ngữ.

Trong bài viết này chúng ta sẽ tìm hiểu một số phương thức thường được dùng để thao tác với các phần tử mảng trong Javascript.

Trong PHP bạn có thể khai báo mảng bằng rất nhiều cách ngắn gọn trong đó có một cách rất đơn giản là sử dụng dấu ngoặc vuông "[]" khi nào cần sử dụng mảng mà không cần phải khai báo trước, trong dấu ngoặc vuông có thể bỏ trống và PHP sẽ tự gán key cho mảng đó. Trong Javascript thì bạn không thể khai báo theo cách ngằn gọn giống PHP như trên mà cần phải khai báo mảng trước sau đó mới có thể sử dụng. Cú pháp khai báo mảng của Javascript là new array("phần tử","phần tử",..."").

Một điều nhấn mạnh rằng mảng trong Javascript là một đối tượng, sau đây sẽ là một số phương thức cần thiết để bạn thao tác với mảng:

  1. push("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào cuối mảng
  2. unshift("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào đầu mảng
  3. pop() ->Phương thức sẽ xóa phần tử cuối trong mảng
  4. shift() ->Phương thức sẽ xóa phần tử đầu trong mảng
  5. sort() ->Phương thức sẽ sắp các phần tử mảng theo giá trị tăng dần đồng thời gán lại key theo thứ tự tăng dần, chú ý phương thức chỉ có tác dụng với mảng có key liên tiếp bắt đầu từ 0
  6. concat() ->Phương thức kết hợp hai mảng thành một
  7. slice(ví trí bắt đầu, vị trí kết thúc) ->Phương thức tách ra một mảng con
  8. join() ->Phương thức tạo một chuỗi từ một mảng, đối số là chuỗi nối các giá trị của phần tử trong mảng
  9. reverse() ->Đảo ngược các vị trí phần từ trong mảng đồng thời xắp lại key

Ngoài ra chúng ta còn có một số các phương thức hữu dụng khác như every(), some(), filter(), forEach(), map() tuy nhiên chúng lại không được hổ trợ bởi các trình duyệt cũ như IE7.
Có một phương thức vô cùng mạnh mẽ khác trong javascript đó là phương thức splice(), nó có thể thay thế cho các phương thức như pop(), push(),shift(), unshift() ở trên:

  1. splice(vị trí bắt đầu, số lượng) ->Phương thức sẽ xóa một số phần tử tại vị trí bất kỳ trong mảng
  2. splice(vị trí bắt đầu, số lượng, "phẩn tử mới", "phần tử mới",""...) ->Khi thêm đối số vào phương thức nó sẽ thay thế các phần tử mới vào các phần tử đã xóa.

Chúng ta có thể thấy việc thao tác với các phần tử mảng trong Javascript cũng không có gì khó khăn điều quan trọng là chúng ta biết vận dụng các phương thức của chúng khi cần thiết. Bài viết này tôi chỉ mang hình thức giời thiệu, nếu bạn muốn thực sự làm việc với Javascript thì chí ít bạn cũng phải biết chút ít kiến thức về lập trình căn bản, bạn có thể tự làm ví dụ để hiểu rõ hơn nếu bạn chưa thực sự hiểu về nó.

jQuery basic: CSS Selectors

jQuery thực sự mạnh mẽ thật đúng với slogan "write less, do more", nó là một thư viện JavaScript rất giễ ràng sử dụng nó giúp các nhà thiết kế và phát triển web thêm các các phần tử có sự tương tác và có tính năng động về phía người dùng. Nếu trước kia bạn viết JavaScript mà không sử dụng thư viện thì sẽ rất dài vì bạn phải tự xây dựng thêm các hàm để chọn rồi sử lý phần tử bây giờ mọi thứ trở nên đơn giản và ngắn gọn như bạn viết CSS vậy. Bài viết này sẽ giới thiệu về các biểu thức chọn trong jQuery theo dạng CSS selector.

Element

Để chọn theo tên thẻ sử dụng cú pháp $('tên thẻ')

ID: #myid

Chọn theo tên id của phần tử sử dụng cú pháp $('tên id')

Class: .myclass

Chọn theo tên class của phần tử sử dụng cú pháp $('.tên class'). Có một điều nên chú ý rằng trong cấu trúc hồ sơ của bạn thì class thường được dùng cho nhiều phần tử nên kết quả biểu thức chọn này thường trả về một mảng phần tử.

Descendant: E F

Chọn theo con cháu ví dụ chọn phần tử img là hậu duệ của phần tử a sẽ có cú pháp $('a img')

Child: E > F

Chọn theo thẻ con trực tiếp cú pháp $('tên thẻ > tên thẻ'). Phương pháp chon theo CSS này được hổ trợ trên hầu hết các trình duyệt hiện đại và không hổ trợ trên trình duyệt IE từ phiên bản 6 về trước

Adjacent Sibling: E + F

Chọn những thẻ có cùng phần tử cha và nằm kế nhau tức chúng là anh em của nhau, cú pháp $('tên thẻ + tên thẻ')

General Sibling: E ~ F

Chọn những phần tử F cùng cấp với phần tử E, cú pháp $('tên thẻ ~ tên thẻ')

Multiple Elements: E,F,G

Chọn nhiều phần tử cùng lúc, cú pháp $('tên thẻ, tên thẻ,...')

Nth Child (:nth-child(n))

Chọn phần tử con theo thứ tự chỉ mục n, ở đây nth-child(n) sẽ đánh số từ 1 và đánh chỉ mục với tất cả các thẻ con, trong khi đó nth(n) sẽ đánh số từ 0 và chỉ đánh chỉ mục theo phần tử bạn chọn. Ngoài ra bạn có thể thay n bằng từ khóa even để chọn những phần tử con chẵn hoặc odd để chọn những phần tử con lẻ.

First Child (:first-child)

Chọn phần tử con đầu tiên, cú pháp $('tên thẻ:first-child')

Last Child (:last-child)

Chọn phần tử con cuối cùng, cú pháp $('tên thẻ:last-child')

Only Child :only-child

Chọn tất cả những phần tử chỉ là con, cú pháp $('tên thẻ:only-child')

Not :not(s)

Chọn theo dạng phủ định. Ví dụ

  • $('li:not(.myclass)') Chọn những phần tử li nào không có class tên myclass
  • $('li:not(:last-child)') Chọn những phần tử  li nào không phải là phần tử con cuối cùng

Empty :empty

Chọn những phần tử nào rỗng tức là nó không có con cháu, cú pháp $('phần tử:empty') hoặc $(':empty')

Universal: *

Dấu * sử dụng trong thẻ chọn đại diện cho tất cả các phần tử

Trong những bài viết tiếp theo sẽ giới thiệu về những phương pháp chọn phần tử tiếp theo.

Tham khảo (jQuery Reference Guide and docs.jquery.com)

jQuery basic: Attribute Selectors, Custom Selectors

Bài viết này sẽ giới thiệu cách chọn phần tử theo thuộc tính và giựa theo các tùy chọn về vị trí của phần tử.

Attribute Selectors

Has Attribute: [foo]

Chọn các phần tử có thuộc tính là foo

Attribute Value Equals: [foo=bar]

Chọn các phần tử có thuộc tính foo với giá trị bằng bar

Attribute Value Does Not Equal: [foo!=bar]

Chọn các phần tử không có thuộc tính foo với giá trị bằng bar

Attribute Value Begins: [@foo^=bar]

Chọn các phần tử có thuộc tính foo với giá trị bắt đầu bằng bar

Attribute Value Ends: [@foo$=bar]

Chọn các phần tử có thuộc tính foo với giá trị cuối bằng bar

Attribute Value Contains: [@foo*=bar]

Chọn các phần tử có thuộc tính foo với giá trị có chứa chuỗi bằng bar

Custom Selectors

Even Element (:even)

Chọn các phần tử chẵn, bạn cũng có thể sử dụng :nth-child(even) với chức năng tương tự

Odd Element (:odd)

Chọn các phần tử lẻ, bạn cũng có thể sử dụng :nth-child(odd) với chức năng tương tự

Nth Element (:eq(n), :nth(n))

Chọn phần tử theo thứ tự chỉ mục, phần tử đầu tiên bắt đầu với chỉ mục bằng 0, cách thức chọn này là khác với nth-child(n)

Greater Than :gt(n)

Chọn các phần tử có chỉ mục lớn hơn n, phần tử đầu tiên bắt đầu với chỉ mục bằng 0

Less Than : lt(n)

Chọn các phần tử có chỉ mục nhỏ hơn n, phần tử đầu tiên bắt đầu với chỉ mục bằng 0

First :first

Chọn phần tử đầu tiên, điều này là tương đương với nth(0), eq(0), còn nếu chọn theo phần tử con thì nó tương đương với nth-child(1)

Last :last

Chọn phần tử cuối cùng

Contains :contains(text)

Chọn các phần tử có chứa nội dung text

Visible :visible

Chọn các phần tử đang được hiển thị

Hidden :hidden

Chọn các phần tử đang được ẩn

Ở trên là những cách thức để bạn chọn phần tử trong jQuery, các bài viết thuộc seri jQuery basic chỉ mang hình thức giới thiệu dành cho những ai mới làm quen với jQuery, hoặc cũng là một bài ôn lại cho những ai đã hiểu về nó.

Tham khảo (jQuery Reference Guide and docs.jquery.com)

Biểu thức quy tắc trong javaScript (regular expression)

Cũng như những ngôn ngữ lập trình khác biểu thức quy tắc (regular expression/ RegExp) là một tính năng đắc lực để kiểm tra, so sánh, thay thế, tách, ghép một chuỗi nào đó theo một quy tắc bạn quy định, nếu bạn đã tìm hiểu về biểu thức quy tắc trong ngôn ngữ PHP rồi thì sẽ thấy javaScript cũng có cách quy định tương tự chỉ khác ở một số hàm xử lý biểu thức quy tắc. Có 2 phương thức của RegExp để kiểm tra là exec và test, có một vài phương thức của chuỗi hữu dụng với biểu thức quy tắc là search, match, split, replace.

Trong javaScript ta có 2 cách để khai báo biểu thức quy tắc:

  1. Khai báo với 2 dấu "/" ở đầu và cuối biểu thức
  2. Khai báo thông qua việc tạo đối tượng RegExp

Cách thứ nhất thường dùng nhiều hơn bởi sự đơn giản trong khai báo.

Khi xử lý một chuỗi với biểu thức điều kiện một điều quan trọng là bạn muốn khi áp dụng ký tự có phân biệt chữ in hoa in thường hay không và áp dụng cho đoạn chuỗi đầu tiên tìm được hay tất cả các đoạn chuỗi hợp quy tắc, ta sẽ được tìm hiểu điều này sau đây:

  •  "/quy tắc/" biểu thức có phân biệt chữ in hoa, in thường, và chỉ áp dụng cho đoạn chuỗi đầu tiên tìm thấy đúng quy tắc
  • "/quy tắc/g" biểu thức có phân biệt hoa - thường và áp dụng cho tất cả đoạn chuỗi hợp quy tắc
  • "/quy tắc/i" biểu thức không phân biệt hoa - thường, và chỉ áp dụng cho đoạn chuỗi đầu tiên tìm thấy đúng quy tắc
  •  "/quy tắc/gi" biểu thức không phân biệt hoa - thường, và áp dụng cho tất cả đoạn chuỗi hợp quy tắc

Ví dụ: thay ký tự n bằng dấu "*"

var str = 'Xin chào!, tôi là VANKHUONG 777';
var str1 = str.replace(/n/gi, '*');
document.write(str1);
// Xi* chào!, tôi là VA*KHUO*G 777
var str2 = str.replace(/n/,'*');
document.write(str2);
// Xi* chào!, tôi là VANKHUONG 777

Tiếp theo ta sẽ tìm hiểu cách viết biểu thức quy tắc với cách dùng ký tự đại diện được quy ước trong biểu thức.

Quy tắc về vị trí

  • "^" nghĩa là bắt đầu một chuỗi
  • "$" nghĩa là kết thúc một chuỗi
  • "\b" nghĩa là điểm giữa một ký tự là từ và ký tự không phải là từ, ký tự là từ ở đây là ký tự từ A-z, 0-9
  • "\B" ngược lại với '/b'

Ví du:

var str = 'ngo van khuong';
var str3 = str.replace(/n\b/, '*');
// str3: ngo va* khuong
var str4 = str.replace(/n\B/, '*');
// str4: *go van khuo*g

Quy tắc về những ký tự metasymbol

  • "." đại diện bất kỳ ký tự nào
  • "\d" đại diện cho một ký tự số từ 0-9, tương đương với cách viết [0-9]
  • "\D" đại diện cho một ký tự không phải là kiểu số từ 0-9, ngược lại với "\d"
  • "\s" đại diện cho một ký tự là khoảng trắng
  • "\S" đại diện cho một ký tự không phải là khoảng trắng, ngược lại với "\s"
  • "\w" đại diện cho một ký tự từ A-Z hoặc a-z hoặc 0-9, hoặc ký tự gạch dưới "_"
  • "\W" đại diện cho một ký tự không phải là từ A-Z, a-z, 0-9, ký tự gạch dưới "_"

Ví dụ:

var str = 'Xin chào!, tôi là VANKHUONG 777';
var str5 = str.replace(/\w/g, '*');
// str5: *** **à*!, *ô* *à ********* ***

Quy tắc về số lượng ký tự

  • "x?" nghĩa là một ký tự "x" hoặc không có ký tự nào
  • "x*" nghĩa là một hoặc nhiều ký tự "x" hoặc không có ký tự nào
  • "x+" nghĩa là có ít nhất một ký tự x
  • "x{n}" nghĩa là ký tự x lặp lại n lần
  • "x{n,}" nghĩa là ký tự x lặp lại ít nhất n lần
  • "x{n,m}" nghĩa là ký tự x lặp lại từ n tới m lần

Ví dụ:

var str = 'good night, godgad, gd, gooogle';
var str6 = str.replace(/go?d/gi, '*');
// str6: good night, *gad, *, gooogle
var str7 = str.replace(/g(oo)?d/gi, '*');
// str7: * night, godgad, *, gooogle
var str8 = str.replace(/go*d/gi, '*');
// str8: * night, *gad, *, gooogle
var str9 = str.replace(/go+/gi, '*');
// str9: *d night, *dgad, gd, *gle
var str10 = str.replace(/o{2}/gi, '*');
// str10: g*d night, godgad, gd, gooogle
var str11 = str.replace(/o{2,}/gi, '*');
// str11: g*d night, godgad, gd, g*gle
var str12 = str.replace(/go{1,3}d/gi, '*');
// str12: *d night, *dgad, gd, gooogle

Quy tắc về danh sách ký tự

  • "[...]" trong dấu ngoặc vuông liệt kê danh sách những ký tự hợp quy tắc, có thể dùng dấu gạch giữa "-"giữa 2 ký tự để thể hiện danh sách những ký tự trong khoảng 2 ký tự theo vị trí ASCII của ký tự
  • "[^...]" chức năng thì ngược lại với "[...]" thay vì liệt kê những ký tự hợp quy tắc, nó cho biết bất kỳ ký tự nào ngoài danh sách các ký tự trong dấu ngoặc vuông

Ví dụ:

var str ='ABCDEF, abcdef, 12345';
var str13 = str.replace(/[Ab1]/g, '*');
// str13: *BCDEF, a*cdef, *2345
var str14 = str.replace(/[A-Cd-f1-35]/g, '*');
// str14: ***DEF, abc***, ***4*
var str15 = str.replace(/[^A-f4-5]/g, '*');
// str15: ABCDEF**abcdef*****45

Với biểu thức quy tắc bạn có thể có nhiều cách viết khác nhau cùng theo một quy tắc hay cùng cho bạn kết quả giống nhau, có người viết dài người viết ngắn nhưng miễn sao bạn thấy giễ hiểu là được, nếu bạn viết quen thì biểu thức nhìn sẽ ngắn hơn. Nếu bạn không hiểu rõ các quy ước trong biểu thức quy tắc thì bạn cũng chẳng hiểu người khác viết gì vì đa số những người có kinh nghiệm đều viết biểu thức ngắn và chặt chẽ, hy vọng bạn thấy bài viết này bổ ích và có thể vận dụng nó một cách hiệu quả.