2013-11-03 19 views
7

này:php undertsanding vs tham lam nongreedy phù hợp với

preg_match('~foo(.*?)(bar)?~','foo bar',$m); 

mang lại cho tôi điều này:

Array 
(
    [0] => foo 
    [1] => 
) 

Tôi kinda bối rối về việc này. Tôi nhận được rằng nhóm 1 là cho tôi một chuỗi rỗng, bởi vì nó là một trận đấu lười biếng. Nhưng không nên (bar)? được tham lam và do đó cho tôi chụp nhóm 2?

Có vẻ hợp lý với tôi rằng những gì tôi nên được nhận là

Array 
(
    [0] => foo 
    [1] => 
    [2] => bar 
) 

nơi [1] là một không gian. Chưa hết .. điều này không xảy ra. Tại sao?

+6

** Tắt chủ đề: ** Vui lòng đổi tên thành 'mysqli_noobie ...'. Tìm hiểu về [* statement statements *] (http://j.mp/T9hLWi), và sử dụng [PDO] (http://php.net/pdo) hoặc [MySQLi] (http://php.net/mysqli) - [bài viết này] (http://j.mp/QEx8IB) sẽ giúp bạn quyết định cái nào. Nếu bạn chọn PDO, [đây là hướng dẫn tốt] (http://j.mp/PoWehJ). – HamZa

+1

@HamZa Điều đó khiến tôi cười khúc khích! – IMSoP

+1

Nếu nó hoạt động theo cách bạn mong đợi nó hoạt động, [0] thực sự sẽ là "thanh foo". [0] là trận đấu hoàn chỉnh. –

Trả lời

5

Câu trả lời ở đây đáng ngạc nhiên là đơn giản. Nhóm đầu tiên không khớp với nhau (vào lần đầu tiên), thậm chí không phải là không gian. Nhóm thứ hai cố gắng khớp không gian với "bar", tất nhiên là không thành công. Nếu có bất kỳ thứ gì phía sau mà HAS khớp, động cơ sẽ quay lại và mở rộng nhóm chụp đầu tiên để phù hợp với không gian. Nhưng nó hoàn toàn tốt đẹp như bây giờ (nhóm thứ hai thực sự có thể được emtpy), vì vậy nó chỉ ở lại theo cách đó.

Để sản xuất những gì bạn mong đợi, hãy thử này:

preg_replace('~foo(.*?)(bar)?_~', 'foo bar_', $m); 


Trong chỉnh sửa của bạn, bạn có thêm một nhóm chụp. (. *) bây giờ là 2. Nó phù hợp cho đến khi kết thúc của chuỗi, như bạn nghĩ nó sẽ. Vì vậy, bạn đang ở ngay trên đó, bạn chỉ cần thay đổi ví dụ ^^

+1

vâng tôi nhận ra rằng ngay sau khi tôi đăng nó, và sau đó hiểu nó không phải là người cuối cùng popping "bar", nhưng '(. *)', cảm ơn! – slinkhi

3

Không, hành vi này là chính xác. Từ documentation on lazy matching:

nếu một lượng hóa được theo sau bởi một dấu hỏi, sau đó nó trở nên lười biếng, và thay vào đó phù hợp với số lần tối thiểu có thể

Kể từ (bar)? là không bắt buộc, (.*?) không cần phải khớp với bất kỳ thứ gì để biểu thức chính quy thành công. Vì khoảng cách giữa foothanh không được chụp, biểu thức không thể tiếp tục và khớp với thanh.

2

Mục nhập '0' luôn là kiểu đối sánh đầy đủ trong trường hợp này là foo. Tuy nhiên, Nhóm kết hợp đầu tiên sẽ không khớp với *. Nhóm thứ hai là tùy chọn.

+0

Điều đó không thực sự trả lời câu hỏi. Trên thực tế, nếu nhóm đầu tiên sẽ không được lười biếng, thứ hai sẽ nắm bắt thanh, mặc dù nó vẫn là tùy chọn. –

+0

@JohannesH. huh .. '(foo) (. *) (bar)? 'thực sự cho tôi" thanh "trong' [2] '.. tại sao vậy? – slinkhi

+1

Đó là vì tất cả các nhóm chụp đều tham lam ở đây. Điều đó có nghĩa là chúng khớp với nhau nhiều nhất có thể. (foo) phù hợp với foo (trong [1]), tất nhiên. (. *) khớp với khoảng trắng - và (thanh) (trong [2]). (quán ba)? không khớp (không có [3]) –

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