Từ câu trả lời perlfaq6 's để How do I match a regular expression that's in a variable?:
Chúng tôi không phải mẫu mã hóa cứng vào các nhà điều hành trận đấu (hoặc bất cứ điều gì khác mà làm việc với biểu thức thông thường). Chúng ta có thể đặt mẫu trong một biến để sử dụng sau này.
Toán tử đối sánh là ngữ cảnh trích dẫn kép, vì vậy bạn có thể nội suy biến của bạn giống như chuỗi được trích dẫn kép. Trong trường hợp này, bạn đọc biểu thức chính quy như đầu vào của người dùng và lưu nó trong $ regex. Khi bạn có mẫu trong $ regex, bạn sử dụng biến đó trong toán tử đối sánh.
chomp(my $regex = <STDIN>);
if($string =~ m/$regex/) { ... }
Mọi ký tự đặc biệt biểu thức chính quy trong $ regex vẫn còn đặc biệt và mẫu vẫn phải hợp lệ hoặc Perl sẽ khiếu nại. Ví dụ, trong mẫu này có một dấu ngoặc đơn không có dấu ngoặc đơn.
my $regex = "Unmatched (paren";
"Two parens to bind them all" =~ m/$regex/;
Khi Perl biên dịch biểu thức chính quy, nó xử lý dấu ngoặc đơn khi bắt đầu khớp bộ nhớ.Khi không tìm thấy dấu ngoặc đơn đóng, nó sẽ khiếu nại:
Unmatched (in regex; marked by <-- HERE in m/Unmatched (<-- HERE paren/ at script line 3.
Bạn có thể giải quyết vấn đề này theo nhiều cách tùy theo tình huống của chúng tôi. Trước tiên, nếu bạn không muốn bất kỳ ký tự nào trong chuỗi trở nên đặc biệt, bạn có thể thoát chúng bằng quotemeta trước khi bạn sử dụng chuỗi.
chomp(my $regex = <STDIN>);
$regex = quotemeta($regex);
if($string =~ m/$regex/) { ... }
Bạn cũng có thể thực hiện việc này trực tiếp trong toán tử đối sánh bằng cách sử dụng trình tự \ Q và \ E. \ Q cho Perl biết nơi nào để bắt đầu thoát các ký tự đặc biệt, và \ E cho biết nơi dừng (xem perlop để biết thêm chi tiết).
chomp(my $regex = <STDIN>);
if($string =~ m/\Q$regex\E/) { ... }
Cách khác, bạn có thể sử dụng qr //, toán tử trích dẫn biểu thức chính quy (xem chi tiết hơn). Nó trích dẫn và có lẽ biên dịch mẫu, và bạn có thể áp dụng cờ biểu thức chính quy cho mẫu.
chomp(my $input = <STDIN>);
my $regex = qr/$input/is;
$string =~ m/$regex/ # same as m/$input/is;
Bạn cũng có thể bẫy bất kỳ lỗi nào bằng cách gói một khối eval xung quanh toàn bộ.
chomp(my $input = <STDIN>);
eval {
if($string =~ m/\Q$input\E/) { ... }
};
warn [email protected] if [email protected];
Hoặc ...
my $regex = eval { qr/$input/is };
if(defined $regex) {
$string =~ m/$regex/;
}
else {
warn [email protected];
}
Xem http://stackoverflow.com/questions/1949731/how-can-i-escape-a-literal-string-i- muốn-interpolate-thành-một-regular-expression –
có thể trùng lặp của [Làm thế nào để xử lý các ký tự đặc biệt trong một regex Perl?] (http://stackoverflow.com/questions/576435/how-do-i-handle -special-characters-in-a-perl-regex) – daxim