Hầu hết các biểu thức ở đây giải quyết các trường hợp sử dụng cụ thể duy nhất.
Điều đó không sao, nhưng tôi thích cách tiếp cận "luôn hoạt động".
function regExpEscape(literal_string) {
return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}
Điều này sẽ "thoát hoàn toàn" một chuỗi ký tự cho bất kỳ cách sử dụng nào sau đây trong các biểu thức thông thường:
- Chèn trong một biểu thức chính quy. Ví dụ
new RegExp(regExpEscape(str))
- Chèn trong một lớp nhân vật. Ví dụ
new RegExp('[' + regExpEscape(str) + ']')
- Chèn vào specifier số nguyên. Ví dụ
new RegExp('x{1,' + regExpEscape(str) + '}')
- Thực thi trong các công cụ biểu thức chính quy không phải là JavaScript.
Nhân vật đặc biệt được bảo hiểm:
-
: Tạo một phạm vi nhân vật trong một lớp nhân vật.
[
/ ]
: Bắt đầu / kết thúc một lớp nhân vật.
{
/ }
: Bắt đầu / kết thúc một công cụ xác định số.
(
/ )
: Bắt đầu / kết thúc một nhóm.
*
/ +
/ ?
: Chỉ định loại lặp lại.
.
: Phù hợp với bất kỳ nhân vật.
\
: Thoát khỏi các ký tự và bắt đầu các thực thể.
^
: Chỉ định bắt đầu vùng khớp và phủ định khớp trong một lớp ký tự.
$
: Chỉ định kết thúc vùng khớp.
|
: Chỉ định xen kẽ.
#
: Chỉ định nhận xét trong chế độ giãn cách miễn phí.
\s
: Bỏ qua trong chế độ khoảng cách miễn phí.
,
: Tách các giá trị trong bộ xác định số.
/
: Bắt đầu hoặc kết thúc biểu thức.
:
: Hoàn thành các loại nhóm đặc biệt và một phần của các lớp nhân vật theo phong cách Perl.
!
: Phủ định nhóm độ rộng bằng không.
<
/ =
: Một phần của thông số kỹ thuật nhóm không độ rộng.
Ghi chú:
/
là không thực sự cần thiết trong bất kỳ hương vị của biểu thức thông thường. Tuy nhiên, nó bảo vệ trong trường hợp ai đó (rùng mình) làm eval("/" + pattern + "/");
.
,
đảm bảo rằng nếu chuỗi có nghĩa là một số nguyên trong bộ xác định số, thì nó sẽ gây ra lỗi biên dịch RegExp đúng cách thay vì âm thầm biên dịch sai.
#
và \s
không cần phải thoát trong JavaScript, nhưng thực hiện theo nhiều hương vị khác. Chúng được thoát ở đây trong trường hợp biểu thức chính quy sau đó sẽ được chuyển sang chương trình khác.
Nếu bạn cũng cần chứng minh tương lai biểu thức chính quy chống lại các bổ sung tiềm năng cho các khả năng của công cụ regex JavaScript, tôi khuyên bạn nên sử dụng phép hoang tưởng hơn:
function regExpEscapeFuture(literal_string) {
return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}
Hàm này thoát khỏi mọi ký tự trừ những ký tự được bảo đảm rõ ràng không được sử dụng cho cú pháp trong các hương vị biểu thức chính quy trong tương lai.
Để thực sự vệ sinh, hãy xem xét trường hợp cạnh này:
var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');
Điều này sẽ biên dịch tốt trong JavaScript, nhưng sẽ không có trong một số hương vị khác. Nếu có ý định chuyển sang hương vị khác, trường hợp null s === ''
nên được kiểm tra độc lập, như vậy:
var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
RegExp.escape
hiện đang làm việc và bất cứ ai nghĩ rằng họ có đầu vào có giá trị đều rất sẵn lòng đóng góp. core-js và các polyfill khác cung cấp nó.