Regex để đối sánh các ký hiệu:! $% ^ & * () _ + | ~ - = `{} []:"; '<>?,. /


93

Tôi đang cố gắng tạo thử nghiệm Regex trong JavaScript sẽ kiểm tra một chuỗi để chứa bất kỳ ký tự nào sau đây:

!$%^&*()_+|~-=`{}[]:";'<>?,./

Thêm thông tin nếu bạn quan tâm :)

Nó dành cho một ứng dụng thay đổi mật khẩu khá thú vị mà tôi đang làm việc. Trong trường hợp bạn quan tâm, đây là phần còn lại của mã.

Tôi có một bảng liệt kê các yêu cầu mật khẩu và khi người dùng cuối nhập mật khẩu mới, nó sẽ kiểm tra một mảng Regexes và đặt dấu kiểm vào hàng bảng tương ứng nếu nó ... kiểm tra :) Tôi chỉ cần thêm cái này thay cho mục thứ 4 trong validationmảng.

var validate = function(password){
    valid = true;

    var validation = [
        RegExp(/[a-z]/).test(password), RegExp(/[A-Z]/).test(password), RegExp(/\d/).test(password), 
        RegExp(/\W|_/).test(password), !RegExp(/\s/).test(password), !RegExp("12345678").test(password), 
        !RegExp($('#txtUsername').val()).test(password), !RegExp("cisco").test(password), 
        !RegExp(/([a-z]|[0-9])\1\1\1/).test(password), (password.length > 7)
    ]

    $.each(validation, function(i){
        if(this)
            $('.form table tr').eq(i+1).attr('class', 'check');
        else{
            $('.form table tr').eq(i+1).attr('class', '');
            valid = false
        }
    });

    return(valid);

}

Có, cũng có xác thực phía máy chủ tương ứng!


9
Thật là buồn cười khi câu trả lời cho câu hỏi của bạn nằm ở tiêu đề ngoại trừ việc thoát các ký tự đặc biệt và có dấu gạch chéo phía trước.
sciritai

1
Tại sao không sử dụng .addClass("check").removeClass("check")? Và nhìn thấy if (someBoolean == true)mã luôn khiến tôi quặn lòng. Chỉ cần làm if (someBoolean). Hoặc, tốt hơn, chỉ cần làm $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;.
gilly

+1 @ gill3 thx cho bài đánh giá mã - phản hồi thực sự tuyệt vời. Tôi đã sử dụng những phương pháp ngắn hạn đó trong quá khứ.
pixelbobby

@ gilly3, nó có vẻ hoạt động tốt trong FF nhưng IE8. yêu tay ngắn này. Tôi đang cố gắng tìm hiểu xem IE8 đang làm gì khác đi.
pixelbobby

Câu trả lời:


171

Biểu thức chính quy cho điều này thực sự đơn giản. Chỉ cần sử dụng một lớp ký tự. Dấu gạch nối là một ký tự đặc biệt trong các lớp ký tự, vì vậy nó cần phải là ký tự đầu tiên:

/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/

Bạn cũng cần phải thoát khỏi các siêu ký tự biểu thức chính quy khác.

Chỉnh sửa: Dấu gạch nối đặc biệt vì nó có thể được sử dụng để đại diện cho một loạt các ký tự. Cùng một lớp ký tự này có thể được đơn giản hóa với các phạm vi sau:

/[$-/:-?{-~!"^_`\[\]]/

Có ba phạm vi. '$' thành '/', ':' thành '?', và '{' thành '~'. chuỗi ký tự cuối cùng không thể được biểu diễn đơn giản hơn bằng một dải ô:! "^ _` [].

Sử dụng bảng ACSII để tìm phạm vi cho các lớp ký tự.


Tại sao bộ định lượng \ Q và \ E không được đề cập để thoát khỏi chuỗi ký tự?
SerG

Trước khi tìm ra giải pháp này, tôi đã đi xuống lộ trình loại trừ lớp ký tự: khớp mọi thứ NHƯNG alpha, chữ số, khoảng trắng, v.v.
Pete Alvin

1
Có phải kiến ​​thức thông thường rằng dấu gạch nối phải đứng trước không? Tôi đã đọc hàng tá câu trả lời SO và bảng gian lận regex, đây là lần đầu tiên tôi nghe nói về nó. Câu trả lời của bạn đã cứu tôi rất nhiều kịch tính. Cảm ơn!
CF_HoneyBadger

2
@SerG \Q\Ekhông có tác dụng trong JS RegExp cơ :(/^\Q.\E$/.test('Q+E'); // true
Paul S.

1
@ q4w56 dấu gạch chéo ngược không có trong bộ ký tự được chỉ định trong câu hỏi ban đầu, do đó, không khớp dấu gạch chéo ngược là chính xác. :)
Jeff Hillman

5

Cách đơn giản nhất và ngắn nhất để thực hiện điều này:

/[^\p{L}\d\s@#]/u

Giải trình

[^...] Khớp một ký tự không có trong danh sách dưới đây

  • \p{L} => khớp với bất kỳ loại chữ cái nào từ bất kỳ ngôn ngữ nào

  • \d => khớp một chữ số từ 0 đến chín

  • \s => phù hợp với bất kỳ loại ký tự vô hình nào

  • @# => @và các #ký tự

Đừng quên chuyển ucờ (unicode).


bạn sẽ không cần một ^ để chỉ ra không?
Webber

1
@Webber Không. Họ đang viết hoa và điều này khiến tuyên bố trở nên tiêu cực. ^là cần thiết khi chúng ta sử dụng \w\strong các chữ cái nhỏ.
AmirZpr

3
Điều này không giải thích nó sao cho bên ngoài whoặc bên ngoài s, và vì hai thứ đó không thực sự giao nhau nên nó chỉ cho phép thông qua tất cả các ký tự? (Do đó không lọc bất cứ thứ gì.)
Zael 19/02/19

2
@Zael Bạn nói đúng, biểu thức chính quy như đã nêu ( /[\W\S]/) thực hiện mọi thứ. Một đại diện chính xác hơn về những gì tôi tin rằng Amir sẽ nhận được [^\w\s]. Trước đây, biểu thức chính quy nói rằng "khớp với bất kỳ thứ gì không phải là chữ và số HOẶC không phải là khoảng trắng", như bạn đã đề cập hãy làm mọi thứ vì các ký tự chữ và số không phải là khoảng trắng và ngược lại. Sau đó nói rằng "khớp bất kỳ thứ gì không phải là chữ và số không phải là khoảng trắng". Tất nhiên, các ngoại lệ được áp dụng trong đó các ký tự có dấu (như À) được khớp với [^\w\s].
Jesse

cái này không bao gồm _ char
MikeSchem

4

Câu trả lời

/[\W\S_]/

Giải trình

Điều này tạo ra một lớp ký tự loại bỏ các ký tự từ, ký tự khoảng trắng và thêm lại ký tự gạch dưới (vì gạch dưới là ký tự "từ"). Tất cả những gì còn lại là các ký tự đặc biệt. Các chữ cái viết hoa thể hiện sự phủ định của các chữ cái viết thường của chúng.

\Wsẽ chọn tất cả các ký tự không phải "từ" tương đương với [^a-zA-Z0-9_]
\Ssẽ chọn tất cả các ký tự không phải "khoảng trắng" tương đương với [ \t\n\r\f\v]
_sẽ chọn "_" bởi vì chúng tôi phủ định nó khi sử dụng \Wvà cần thêm lại vào


MikeSchem, bạn vừa đưa tôi qua một cỗ máy thời gian.
pixelbobby

yea, tôi nhận thấy nó. đã cũ, nhưng tôi cảm thấy câu trả lời đơn giản nhất đã không được đăng.
MikeSchem

Câu trả lời này khác với câu trả lời không có gạch dưới như thế nào?
sf8193

vâng, bạn nói đúng, tôi sẽ sửa đổi điều này
MikeSchem

-1
// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflict
  const hasSpecial = password => {
    const specialReg = new RegExp(
      '^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',
    );
    return specialReg.test(password);
  };

Không sử dụng hàm RegExptạo khi bạn chỉ có thể sử dụng một ký tự regex. Công việc thoát ít hơn nhiều (dù sao hầu hết đều không cần thiết) và nó cũng hiệu quả hơn.
Bergi

Tại sao phải sử dụng lookahead phức tạp khi bạn chỉ có thể khớp trực tiếp với nhân vật?
Bergi

Bạn có thể cho một ví dụ @Bergi không? Tôi không hiểu những gì bạn đang đề nghị.
Arni Gudjonsson

-1

Một cách đơn giản để đạt được điều này là tập hợp âm [^ \ w \ s]. Điều này về cơ bản bắt:

  • Bất kỳ thứ gì không phải là ký tự chữ và số (chữ cái và số)
  • Bất kỳ thứ gì không phải là khoảng trắng, tab hoặc ngắt dòng (được gọi chung là khoảng trắng)

Vì một số lý do [\ W \ S] không hoạt động theo cùng một cách, nó không thực hiện bất kỳ quá trình lọc nào. Nhận xét của Zael về một trong những câu trả lời cung cấp một điều gì đó giải thích.


Không, dấu gạch dưới bị thiếu và tất cả các ký tự ngoài phạm vi ascii và hầu hết các ký tự điều khiển trong phạm vi ascii sẽ khớp với lớp này. /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Casimir et Hippolyte

-7

Thay thế tất cả các độ trễ từ bất kỳ ngôn ngữ nào bằng 'A' và nếu bạn muốn, ví dụ: tất cả các chữ số thành 0:

return str.replace(/[^\s!-@[-`{-~]/g, "A").replace(/\d/g, "0");

22
Bạn đang trả lời câu hỏi nào?
Toto
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.