2012-04-30 17 views
8

Tự hỏi nếu có ai ngoài kia có thể làm sáng tỏ về lý do tại sao các biểu thức chính quy sau đây là không khi sử dụng chức năng preg_match PHP: -"preg_match(): Compilation failed: ngoặc chưa từng có" trong PHP cho mô hình hợp lệ

<?php 
$str = '\tmp\phpDC1C.tmp'; 

preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); 

print_r($matches); 
?> 

Điều này dẫn đến thông báo lỗi "preg_match(): Biên soạn không thành công: dấu ngoặc đơn chưa khớp" mặc dù thực tế là mẫu có vẻ hợp lệ. Tôi đã thử nghiệm nó với một số trực tuyến PHP Regular Expression tester và công cụ Linux Kiki. Có vẻ như PHP đang thoát khỏi dấu mở ngoặc chứ không phải dấu gạch chéo ngược.

Tôi đã giải quyết vấn đề bằng cách sử dụng str_replace để hoán đổi dấu gạch chéo ngược cho các chuyển tiếp. Điều này làm việc cho tình hình của tôi nhưng nó sẽ được tốt đẹp để biết tại sao biểu thức chính quy này là không.

Trả lời

15

Để mã hóa một dấu chéo ngược theo nghĩa đen, bạn cần phải thoát khỏi nó hai lần: Một lần cho chuỗi, và một lần cho động cơ regex:

preg_match('|\\\\tmp\\\\([A-Za-z0-9]+)|', $str, $matches); 

Trong PHP (khi sử dụng chuỗi đơn trích dẫn), điều này chỉ là liên quan đến các dấu gạch chéo ngược thực tế; thoát regex khác là OK với một dấu gạch chéo duy nhất:

preg_match('/\bhello\b/', $subject) 

này được bao phủ trong the manual (xem hộp có nhãn "Lưu ý:" ở phía trên cùng của trang).

+1

Nó được kèm theo trong dấu nháy đơn, là nó thực sự cần thiết để thoát khỏi nó hai lần? – Zombaya

+0

Thực hiện tốt, nhắc tôi về một số regexe điên mà tôi đã sử dụng trong quá khứ, ví dụ: 'sed/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ – Petah

+0

@Zombaya: Có, nhưng chỉ khi đó là một dấu gạch chéo ngược thực sự bạn đang cố mã hóa. –

0

lạ tôi chỉ kiểm tra bằng cách sử dụng cùng một thử nghiệm regex trực tuyến mà bạn đề cập và nó được biên dịch mà không có lỗi:

<?php 
$ptn = "/<;?php $str = '\tmp\phpDC1C.tmp'; 
preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); print_r($matches); ?>;/"; 
$str = ""; 
preg_match($ptn, $str, $matches); 
print_r($matches); 
?> 
+0

Xin lỗi, có thể không rõ ràng trong câu hỏi của tôi nhưng công cụ trực tuyến chấp nhận nó là hợp lệ, nhưng nó không thành công trong mã thực tế của tôi (ngay cả khi sử dụng đầu ra mã từ công cụ). Cụm từ thông dụng phải hợp lệ. – drmonkeyninja

1

bạn phải sử dụng |\\\tmp\\\([A-Za-z0-9]+)| biểu

nhưng có những cách tốt hơn để có được tên tập tin vì dạng bê tông của chuỗi. ví dụ:

substr($str, 5, -4); 

nghĩ về việc sử dụng bộ nhớ

+0

Giá trị của $ str của tôi chỉ là một ví dụ. Cách tốt nhất để lấy giá trị của tên tệp trong PHP sẽ là sử dụng hàm pathinfo. – drmonkeyninja

0

Sử dụng regex tiếp theo:

php >$str = '\tmp\phpDC1C.tmp'; 
php >preg_match('/[\\\\]tmp[\\\\]([A-Za-z0-9]+)/', $str, $matches); 
php >print_r($matches); 
Array 
(
    [0] => \tmp\phpDC1C 
    [1] => phpDC1C 
) 
Các vấn đề liên quan