2017-11-30 21 views
6

Thay thế văn bản perl rất đơn giản và mạnh mẽ. tôi muốn làm một kịch bản với sự thay thế biến, như:Cách đăng ký với các tùy chọn thay đổi trong tập lệnh perl

if ($IgnoreCase) {$opt = "gi"} else {$opt = "g"} 

$string =~ s/$source/$replace/$opt; 

Kết quả trong:

Scalar tìm thấy nơi khai thác dự kiến ​​...

Có posibility để làm biến tùy chọn?

Trả lời

13

Vì bạn đang sử dụng /g trong mọi trường hợp bạn có thể,

my $opt = $IgnoreCase ? "(?i)" : ""; 

$string =~ s/$opt$source/$replace/g; 

Thông tin thêm về chủ đề này trong perldoc perlre

Một hoặc nhiều nhúng bổ mô hình trận đấu, phải được bật (hoặc tắt nếu trước "-") cho phần còn lại của mẫu hoặc phần còn lại của nhóm mẫu bao quanh (nếu có).

Điều này đặc biệt hữu ích đối với các mẫu được tạo động, chẳng hạn như các mẫu được đọc từ tệp cấu hình, được lấy từ một đối số hoặc được chỉ định trong bảng ở đâu đó. Hãy xem xét trường hợp một số mẫu muốn phân biệt chữ hoa chữ thường và một số mẫu không phân biệt chữ hoa chữ thường: Các chữ cái không phân biệt dạng chữ chỉ cần bao gồm (? I) ở phía trước mẫu.

+1

Bạn có thể giải thích một chút – ssr1012

+0

Cảm ơn bạn đã trả lời nhanh. Nó woks hoàn hảo hình thành tôi. – Horst

+3

Những thứ như 'i' có thể được cung cấp khi chạy bằng cách sử dụng dấu ngoặc vuông để bật và tắt chúng lần nữa. Bạn không thể làm điều này với 'g' mặc dù, bởi vì nó cơ bản làm thay đổi hành vi của động cơ regex. – Sobrique

7

Để hơi rõ the excellent answer từ Сухой27:

Như bạn đã thấy, bạn không thể sử dụng một biến trong các tùy chọn phần của các nhà điều hành s/// (tốt, bạn có thể nếu bạn sử dụng eval nhưng đó sẽ là một ý tưởng rất xấu).

Tuy nhiên, đó không phải là cách duy nhất để đưa các tùy chọn vào đối sánh regex. Bạn cũng có thể sử dụng cú pháp (?...)bên trong chuỗi regex. Ví dụ: m/(?i)foo/ chính xác giống như m/foo/i. Lưu ý rằng /g là một lớp tùy chọn hơi khác, do đó bạn không thể sử dụng tùy chọn đó như thế này.

Nhưng vì chuỗi (?...) này chỉ là một phần của regex, bạn có thể sử dụng biến để nhúng nó vào trong regex của mình.

my $opt = $IgnoreCase ? "(?i)" : ""; 

$string =~ s/$opt$source/$replace/g; 

Xem "Extended Patterns" in perldoc perlre để biết thêm chi tiết.

+0

Có cách nào cho lớp tùy chọn này (như/g) biến không? – Horst

+2

@Horst: Không, vì tùy chọn '/ g' thay đổi cách động cơ regex hoạt động theo các cách cơ bản - và khi động cơ đã khởi động, đã quá muộn để thay đổi. –

+0

Một cách khác để xử lý điều này sẽ là một toán tử đại học hoặc một cấu trúc điều khiển if-else không đơn giản cung cấp các tùy chọn thích hợp, nhưng đi xa hơn và cung cấp toàn bộ regex. Sau đó, các/g tùy chọn có thể được trong một và không phải là khác. –

Các vấn đề liên quan