2014-04-28 15 views
7

Vớiphp preg_match trở lại vị trí của trận đấu cuối cùng

preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE); 

là nó có thể để tìm kiếm một chuỗi trong ngược? I E. trả lại vị trí của lần xuất hiện cuối cùng của mẫu trong chủ đề tương tự như strripos

Hoặc tôi phải trả lại vị trí của tất cả các kết quả phù hợp với preg_match_all và sử dụng thành phần cuối cùng của $matches?

+1

Hãy nêu rõ, *** TÔI CÓ NÀY VÀ TÔI CẦN OUTPUT NÀY ***, giúp chúng tôi để giúp bạn. –

Trả lời

16

PHP không có một phương pháp regex mà tìm kiếm một chuỗi từ phải sang trái (như trong .net). Có một số cách có thể để giải quyết rằng:

  • sử dụng preg_match_all với PREG_SET_ORDER cờ và end($matches) sẽ cung cấp cho bạn những trận đấu cuối cùng thiết lập
  • đảo ngược chuỗi với strrev và xây dựng một "đảo ngược" mẫu mà bạn sử dụng với preg_match
  • sử dụng preg_match và tạo mẫu được neo ở cuối chuỗi để đảm bảo không còn xuất hiện mặt nạ được tìm kiếm nữa cho đến khi kết thúc chuỗi
  • sử dụng định lượng tham lam trước và sử dụng \K để bắt đầu e kết quả trận đấu ở vị trí bạn muốn. Khi đã kết thúc chuỗi, công cụ regex sẽ quay lại cho đến khi tìm thấy kết quả phù hợp.

dụ với chuỗi $str = 'xxABC1xxxABC2xx' và cho mô hình /x[A-Z]+\d/

cách 1:

preg_match_all('/x[A-Z]+\d/', $str, $matches, PREG_SET_ORDER); 
print_r(end($matches)); 

cách 2:

if (preg_match('/\d[A-Z]+x/', strrev($str), $match)) 
    print_r(strrev($match[0])); 

cách 3:

preg_match('/x[A-Z]+\d(?=(?:(?!x[A-Z]+\d).)*$)/', $str, $match); 

cách 3 (biến thể):

preg_match('/x[A-Z]+\d(?!.*x[A-Z]+\d)/', $str, $match); 

cách 4:

preg_match('/^.*\Kx[A-Z]+\d/', $str, $match); 

cách 4 (biến thể): để hạn chế thụt lùi bước, bạn có thể gửi kèm theo khối có thể vào một nhóm nguyên tử:

preg_match('/^(?>x[A-Z]+\d|[^x]+|x(?![A-Z]+\d))*\Kx[A-Z]+\d/', $str, $match); 
+0

Đã đi với phương pháp nắm tay, tôi không biết nếu có một số chi phí không cần thiết trong trả lại tất cả các trận đấu nhưng nó hoạt động tốt – andrew

+1

Câu trả lời tuyệt vời thưa ông. –

0

preg_match không hỗ trợ tìm kiếm ngược vì không cần thiết.

Bạn có thể tạo RegExp có chứa tham lam (mặc định) mặc định khớp với bất kỳ thứ gì (như (?<=.*)stuff). Bằng cách này bạn sẽ có được sự xuất hiện cuối cùng của trận đấu của bạn.

thông tin chi tiết từ tài liệu chính thức ở đây: preg_match

+0

'(? <=. *)' Là một lookbehind lookbehind và không giới hạn chiều dài không được hỗ trợ bởi php. – stema

+0

chính xác, tôi trộn hai tên, xin lỗi. Tôi không biết rằng php không hỗ trợ điều đó. – Jonny007

1

Tôi không hiểu chính xác những gì bạn muốn, bởi vì nó phụ thuộc vào bao nhiêu nhóm sẽ được chụp, tôi đã thực hiện một chức năng để nắm bắt bù đắp của việc thu thập cuối cùng phù hợp vào số nhóm, theo mẫu của tôi, có 3 nhóm: nhóm đầu tiên, chụp toàn bộ và hai nhóm, nhóm phụ khác.

mẫu mã ví dụ:

$pattern = "/<a[^\x3e]{0,}href=\x22([^\x22]*)\x22>([^\x3c]*)<\/a>/"; 

mẫu mã HTML:

$subject = '<ul> 
<li>Search Engines</li> 
<li><a href="https://www.google.com/">Google</a></li> 
<li><a href="http://www.bing.com/">Bing</a></li> 
<li><a href="https://duckduckgo.com/">DuckDuckGo</a></li> 
</ul>'; 

Chức năng của tôi, nó nắm bắt được bù đắp trong những yếu tố cuối cùng và bạn có khả năng để chỉ ra số lượng phù hợp:

function get_offset_last_match($pattern, $subject, $number) { 
    if (preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE) == false) { 
     return false; 
    } 
    return $matches[$number][count($matches[0]) - 1][1]; 
} 

Bạn có thể nhận thông tin chi tiết về preg_match_all here về tài liệu chính thức.

Sử dụng mô hình của tôi ví dụ:

0 => tất cả văn bản
1 => href giá trị
2 => innerHTML

echo '<pre>'; 
echo get_offset_last_match($pattern, $subject, 0) . PHP_EOL; // all text 
echo get_offset_last_match($pattern, $subject, 1) . PHP_EOL; // href value 
echo get_offset_last_match($pattern, $subject, 2) . PHP_EOL; // innerHTML 
echo '</pre>'; 
die(); 

Output là:

140 
149 
174 

My chức năng (văn bản):

function get_text_last_match($pattern, $subject, $number) { 
    if (preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE) == false) { 
     return false; 
    } 
    return $matches[$number][count($matches[0]) - 1][0]; 
} 

Mẫu mã:

echo '<textarea style="font-family: Consolas: font-size: 14px; height: 200px; tab-size: 4; width: 90%;">'; 
echo 'ALL = ' . get_text_last_match($pattern, $subject, 0) . PHP_EOL; // all text 
echo 'HREF = ' . get_text_last_match($pattern, $subject, 1) . PHP_EOL; // href value 
echo 'INNER = ' . get_text_last_match($pattern, $subject, 2) . PHP_EOL; // innerHTML 
echo '</textarea>'; 

Output là:

ALL = <a href="https://duckduckgo.com/">DuckDuckGo</a> 
HREF = https://duckduckgo.com/ 
INNER = DuckDuckGo 
+0

Cảm ơn thông tin chi tiết +1 – andrew

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