Số lượng tham lam so với miễn cưỡng so với số lượng sở hữu


357

Tôi tìm thấy hướng dẫn tuyệt vời này về các biểu thức chính quy và trong khi tôi trực giác hiểu được các số lượng "tham lam", "miễn cưỡng" và "sở hữu" làm gì, dường như có một lỗ hổng nghiêm trọng trong sự hiểu biết của tôi.

Cụ thể, trong ví dụ sau:

Enter your regex: .*foo  // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // possessive quantifier
Enter input string to search: xfooxxxxxxfoo
No match found.

Lời giải thích đề cập đến việc ăn toàn bộ chuỗi đầu vào, các chữ cái đã được sử dụng , sao lưu trùng khớp , sự xuất hiện ngoài cùng bên phải của "foo" đã được lấy lại , v.v.

Thật không may, mặc dù những ẩn dụ tốt đẹp, tôi vẫn không hiểu những gì được ăn bởi ai ... Bạn có biết một hướng dẫn khác giải thích (chính xác) cách các công cụ biểu thức chính quy hoạt động không?

Ngoài ra, nếu ai đó có thể giải thích theo một số cụm từ khác nhau, đoạn đó sẽ được đánh giá cao:

Ví dụ đầu tiên sử dụng bộ định lượng tham lam. * Để tìm "bất cứ thứ gì", không hoặc nhiều lần, theo sau là các chữ cái "f" "o" "o". Bởi vì bộ định lượng là tham lam, phần. * Của biểu thức trước tiên ăn toàn bộ chuỗi đầu vào. Tại thời điểm này, biểu thức tổng thể không thể thành công, vì ba chữ cái cuối cùng ("f" "o" "o") đã được sử dụng ( bởi ai? ). Vì vậy, trình so khớp từ từ lùi lại ( từ phải sang trái? ) Một chữ cái tại một thời điểm cho đến khi sự xuất hiện ngoài cùng bên phải của "foo" đã được lấy lại ( điều này có nghĩa là gì? ), Tại thời điểm đó, trận đấu kết thúc và quá trình tìm kiếm kết thúc.

Tuy nhiên, ví dụ thứ hai là miễn cưỡng, vì vậy nó bắt đầu bằng cách tiêu thụ đầu tiên ( bởi ai? ) "Không có gì". Vì "foo" không xuất hiện ở đầu chuỗi, nên nó buộc phải nuốt ( ai nuốt?) Chữ cái đầu tiên ("x"), kích hoạt trận đấu đầu tiên ở 0 và 4. Khai thác thử nghiệm của chúng tôi tiếp tục quá trình cho đến khi chuỗi đầu vào cạn kiệt. Nó tìm thấy một trận đấu khác tại 4 và 13.

Ví dụ thứ ba không tìm thấy kết quả khớp vì bộ định lượng là sở hữu. Trong trường hợp này, toàn bộ chuỗi đầu vào được sử dụng bởi. * +, ( Làm thế nào? ) Không để lại gì để đáp ứng "foo" ở cuối biểu thức. Sử dụng một bộ định lượng sở hữu cho các tình huống mà bạn muốn nắm bắt tất cả mọi thứ mà không bao giờ lùi lại ( điều đó có nghĩa là gì? ); nó sẽ vượt trội hơn bộ định lượng tham lam tương đương trong trường hợp không tìm thấy kết quả khớp ngay lập tức.


22
Tối đa quantifiers thích *, +?tham lam. Tối thiểu quantifiers thích *?, +???lười biếng. Sở hữu quantifiers thích *+, ++?+dính.
tchrist

6
Câu hỏi này đã được thêm vào Câu hỏi thường gặp về Biểu hiện thường xuyên của Stack Overflow , trong phần "Định lượng> Thêm về sự khác biệt ...".
aliteralmind

Quan tâm: Hướng dẫn Java ™ - Sự khác biệt giữa các bộ lượng tử tham lam, miễn cưỡng và sở hữu - Cuộn xuống để xem phần.
Guy Coder

Câu trả lời:


495

Tôi sẽ cho nó một viên đạn.

Một bộ định lượng tham lam đầu tiên phù hợp với càng nhiều càng tốt. Vì vậy, .*phù hợp với toàn bộ chuỗi. Sau đó, trình so khớp cố gắng khớp với các mục fsau, nhưng không còn ký tự nào. Vì vậy, nó "quay lại", làm cho bộ lượng hóa tham lam khớp với một ký tự ít hơn (để lại chữ "o" ở cuối chuỗi không khớp). Điều đó vẫn không khớp với biểu thức chính fquy, do đó, nó quay lại một bước nữa, làm cho bộ định lượng tham lam khớp với một ký tự ít hơn một lần nữa (để lại "oo" ở cuối chuỗi không khớp). Điều đó vẫn không khớp với fregex, do đó, nó quay lại một bước nữa (để lại "foo" ở cuối chuỗi không khớp ). Bây giờ, trình so khớp cuối cùng cũng khớp với biểu thức fchính quy,oođược kết hợp quá. Sự thành công!

Một bộ định lượng miễn cưỡng hoặc "không tham lam" trước hết khớp với ít nhất có thể. Vì vậy, các .*trận đấu không có gì lúc đầu, khiến cho toàn bộ chuỗi không thể so sánh được. Sau đó, trình so khớp cố gắng khớp với các phần fsau, nhưng phần không khớp của chuỗi bắt đầu bằng "x" để không hoạt động. Vì vậy, các backtracks khớp, làm cho bộ định lượng không tham lam khớp với một ký tự nữa (bây giờ nó khớp với "x", để lại "fooxxxxxxfoo" không thể so sánh được). Sau đó, nó cố gắng để khớp f, cái nào thành công, ovà cái tiếp theo otrong regex cũng khớp. Sự thành công!

Trong ví dụ của bạn, nó sẽ bắt đầu quá trình với phần chưa từng có của chuỗi, "xxxxxxfoo", theo cùng quy trình.

Bộ định lượng sở hữu giống như bộ định lượng tham lam, nhưng nó không quay lại. Vì vậy, nó bắt đầu với việc .*khớp toàn bộ chuỗi, không để lại gì cả. Sau đó, không còn gì cho nó phù hợp với ftrong regex. Vì bộ định lượng sở hữu không quay lại, nên trận đấu thất bại ở đó.


15
+1 Câu trả lời hay. Tôi sẽ chỉ thêm: Đi đọc Làm chủ các biểu thức chính quy (Ấn bản thứ 3)
Ridgerunner

@Anomie hơi muộn một chút, nhưng trong phần sở hữu, tôi nghĩ bạn có nghĩa là nó bắt đầu với .*+ (chú ý "+")
RD

3
chính xác thì định lượng sở hữu làm gì sau đó? nếu nó không phù hợp với điều này? (Ý tôi là điểm của nó là gì, nếu bạn không thể có các ký tự sau nó)
tái hiện

4
@relipse: Bạn sẽ sử dụng nó trong tình huống mà bạn biết rằng quay lui sẽ không giúp ích gì, có lẽ không .*+phù hợp với mọi thứ. Ví dụ: nếu bạn có một mẫu [xyz]*foo, không có cách nào để quay lại x, y và z khớp với[xyz]* bit sẽ cho phép các foobit sau khớp với nhau, vì vậy bạn có thể tăng tốc mọi thứ bằng cách làm cho nó có tính sở hữu.
Anomie

4
@moodboom, không có trường hợp nào (thực tế toán học) trong đó các bộ lượng hóa sở hữu sẽ tạo ra một trận đấu sẽ không được tạo ra bởi các bộ lượng hóa tham lam đơn giản. Thỉnh thoảng có những trường hợp họ sẽ tạo ra một trận đấu khi các bộ lượng tử tham lam sẽ tạo ra một trận đấu. Đối với TẤT CẢ các trường hợp khác (trong đó tham lam và sở hữu tạo ra kết quả tương tự), các bộ lượng hóa sở hữu mang lại hiệu suất.
tự đại diện

49

Nó chỉ là đầu ra thực hành của tôi để hình dung cảnh-

Hình ảnh trực quan


3
Ngoại trừ tôi nghĩ trường hợp cuối cùng, sở hữu, không nên có n vượt qua - chỉ cần lấy toàn bộ chuỗi cùng một lúc.
đối xử tốt với các mod của bạn vào

@phyzome Mình nghĩ bây giờ ổn chứ?
SIslam

1
Cảm ơn lời giải thích trực quan :)
Lars Moelleken

Trong EXPRESSION .*?foo(), các [f] [o] [o]hình chữ nhật có nên có màu vàng 5th passkhông?
tonix

1
@tonix vâng! Màu vàng cần phải được thực hiện cho phần phù hợp trong biểu thức .*?foo.*+foo.
SIslam

24

Tôi chưa từng nghe các thuật ngữ chính xác 'hồi sinh' hoặc 'lùi lại' trước đó; cụm từ sẽ thay thế những từ này là "quay lui", nhưng "hồi sinh" có vẻ như là một cụm từ tốt như bất kỳ nội dung nào cho "nội dung đã được chấp nhận tạm thời trước khi quay lại ném nó đi một lần nữa".

Điều quan trọng để nhận ra về hầu hết các công cụ regex là chúng quay lại : chúng sẽ tạm thời chấp nhận một trận đấu tiềm năng, một phần, trong khi cố gắng khớp toàn bộ nội dung của regex. Nếu regex không thể được khớp hoàn toàn ở lần thử đầu tiên, thì công cụ regex sẽ quay lại trên một trong các trận đấu của nó. Nó sẽ cố gắng khớp *, +, ?, luân phiên, hoặc {n,m}lặp lại khác nhau, và thử lại. (Và vâng, quá trình này có thể mất nhiều thời gian.)

Ví dụ đầu tiên sử dụng bộ định lượng tham lam. * Để tìm "bất cứ thứ gì", không hoặc nhiều lần, theo sau là các chữ cái "f" "o" "o". Bởi vì bộ định lượng là tham lam, phần. * Của biểu thức trước tiên ăn toàn bộ chuỗi đầu vào. Tại thời điểm này, biểu thức tổng thể không thể thành công, vì ba chữ cái cuối cùng ("f" "o" "o") đã được sử dụng ( bởi ai? ).

Ba chữ cái cuối cùng, f, o, và ođã được tiêu thụ bởi các ban đầu .*phần của quy tắc. Tuy nhiên, phần tử tiếp theo trong regex, fkhông còn gì trong chuỗi đầu vào. Động cơ sẽ bị buộc phải quay lại trên .*trận đấu ban đầu của nó và thử khớp với tất cả các nhân vật cuối cùng. (Nó có thể là thông minh và quay lại tất cả, nhưng cuối cùng, bởi vì nó có ba thuật ngữ theo nghĩa đen, nhưng tôi không biết về chi tiết thực hiện ở cấp độ này.)

Vì vậy, trình so khớp từ từ lùi lại ( từ phải sang trái? ) Một chữ cái tại một thời điểm cho đến khi sự xuất hiện ngoài cùng bên phải của "foo" đã được lấy lại ( điều này có nghĩa là gì? ), Tại đó

Điều này có nghĩa là foođã dự kiến bao gồm cả khi phù hợp .*. Vì nỗ lực đó đã thất bại, công cụ regex cố gắng chấp nhận ít hơn một ký tự .*. Nếu đã có một trận đấu thành công trước sự .*trong ví dụ này, sau đó động cơ có lẽ sẽ cố gắng rút ngắn .*trận đấu (từ phải sang trái, như bạn chỉ ra, vì nó là một vòng tham lam), và nếu nó không thể phù hợp toàn bộ đầu vào, sau đó nó có thể bị buộc phải đánh giá lại những gì nó đã xuất hiện trước khi các .*trong ví dụ giả thuyết của tôi.

điểm trận đấu thành công và kết thúc tìm kiếm.

Tuy nhiên, ví dụ thứ hai là miễn cưỡng, vì vậy nó bắt đầu bằng cách tiêu thụ đầu tiên ( bởi ai? ) "Không có gì". Vì "foo"

Không có gì ban đầu được tiêu thụ bởi .?*, nó sẽ tiêu thụ số lượng ngắn nhất có thể của bất cứ thứ gì cho phép phần còn lại của regex khớp.

không xuất hiện ở đầu chuỗi, nó buộc phải nuốt ( ai nuốt?)

Một lần nữa .?*, nhân vật tiêu thụ đầu tiên, sau khi quay lại thất bại ban đầu để khớp toàn bộ regex với trận đấu ngắn nhất có thể. (Trong trường hợp này, công cụ regex sẽ mở rộng trận đấu .*?từ trái sang phải, vì .*?miễn cưỡng.)

chữ cái đầu tiên ("x"), kích hoạt kết quả khớp đầu tiên ở 0 và 4. Khai thác thử nghiệm của chúng tôi tiếp tục quá trình cho đến khi hết chuỗi đầu vào. Nó tìm thấy một trận đấu khác tại 4 và 13.

Ví dụ thứ ba không tìm thấy kết quả khớp vì bộ định lượng là sở hữu. Trong trường hợp này, toàn bộ chuỗi đầu vào được sử dụng bởi. * +, (Bằng cách nào? )

A .*+sẽ tiêu thụ càng nhiều càng tốt, và sẽ không quay lại để tìm trận đấu mới khi toàn bộ regex không tìm thấy trận đấu. Vì hình thức sở hữu không thực hiện quay lui, bạn có thể sẽ không thấy nhiều cách sử dụng .*+, mà thay vào đó là với các lớp ký tự hoặc các hạn chế tương tự : account: [[:digit:]]*+ phone: [[:digit:]]*+.

Điều này có thể tăng tốc độ khớp regex một cách mạnh mẽ, bởi vì bạn đang nói với công cụ regex rằng nó sẽ không bao giờ quay lại các đối sánh tiềm năng nếu đầu vào không khớp. (Nếu bạn phải viết tất cả mã phù hợp bằng tay, thì điều này sẽ tương tự như không bao giờ sử dụng putc(3)để 'đẩy lùi' một ký tự đầu vào. Nó sẽ rất giống với mã ngây thơ mà người ta có thể viết trong lần thử đầu tiên. tốt hơn so với một nhân vật đẩy lùi, họ có thể tua lại tất cả trở về số 0 và thử lại. :)

Nhưng hơn cả khả năng tăng tốc độ tiềm năng, điều này cũng có thể cho phép bạn viết các biểu thức chính xác phù hợp với chính xác những gì bạn cần để khớp. Tôi gặp khó khăn khi đưa ra một ví dụ dễ hiểu :) nhưng viết một biểu thức chính bằng cách sử dụng các bộ lượng hóa sở hữu và tham lam có thể cung cấp cho bạn các kết quả khác nhau, và cái này có thể phù hợp hơn.

không để lại gì để thỏa mãn "foo" ở cuối biểu thức. Sử dụng một bộ định lượng sở hữu cho các tình huống mà bạn muốn nắm bắt tất cả mọi thứ mà không bao giờ lùi lại ( điều đó có nghĩa là gì? ); nó sẽ tốt hơn

"Backing off" trong ngữ cảnh này có nghĩa là "quay lui" - ném đi một phần trận đấu dự kiến ​​để thử một trận đấu một phần khác, có thể hoặc không thể thành công.

bộ định lượng tham lam tương đương trong trường hợp không tìm thấy kết quả khớp ngay lập tức.


2
Tôi nghi ngờ rằng không bao giờ có trường hợp một bộ định lượng sở hữu sẽ khớp với thứ mà một bộ định lượng tham lam sẽ không có. Tôi tin rằng những điều sau đây đã chứng minh điều đó: Một bộ định lượng tham lam luôn khớp càng nhiều càng tốt, sau đó quay lại nếu không thể tìm thấy kết quả khớp. Bộ định lượng sở hữu khớp với càng nhiều càng tốt, sau đó thoát ra nếu không thể tìm thấy kết quả khớp. Vì vậy, có thể có một cái gì đó mà một bộ lượng hóa tham lam phù hợp với bộ lượng hóa sở hữu sẽ không, nhưng không phải là ngược lại, bởi vì cả hai đều tìm kiếm "cái cây" theo cùng một trình tự, bộ định lượng sở hữu chỉ từ bỏ dễ dàng hơn. ;)
Thẻ đại diện

2
Khẳng định: "Đó là những gì nhóm nguyên tử và định lượng sở hữu dành cho: hiệu quả bằng cách không cho phép quay lui." từ normal-expressions.info Vì vậy, tuyên bố trong câu trả lời này "Nhưng hơn cả khả năng tăng tốc độ tiềm năng, điều này cũng có thể cho phép bạn viết regex phù hợp chính xác với những gì bạn cần khớp." thực sự không hoàn toàn chính xác
tự đại diện

1
@Wildcard, cảm ơn các ý kiến; điều đó có thể giải thích tại sao tôi gặp khó khăn khi đưa ra một ví dụ. Hehe.
đăng

19

http://swtch.com/~rsc/regapi/regapi1.html

Tôi không chắc đó là lời giải thích tốt nhất trên internet, nhưng nó được viết một cách hợp lý và chi tiết phù hợp, và tôi tiếp tục quay lại với nó. Bạn có thể muốn kiểm tra nó.

Nếu bạn muốn một mức độ cao hơn (giải thích ít chi tiết hơn), đối với các biểu thức chính quy đơn giản như biểu thức bạn đang xem, một công cụ biểu thức chính quy hoạt động bằng cách quay lại. Về cơ bản, nó chọn ("ăn") một phần của chuỗi và cố gắng khớp biểu thức chính quy với phần đó. Nếu nó phù hợp, tuyệt vời. Nếu không, động cơ sẽ thay đổi phần lựa chọn của chuỗi và cố gắng khớp với biểu thức chính quy với phần đó, v.v., cho đến khi nó thử mọi lựa chọn có thể.

Quá trình này được sử dụng một cách đệ quy: trong nỗ lực khớp một chuỗi với một biểu thức chính quy định, công cụ sẽ chia biểu thức chính quy thành các phần và áp dụng thuật toán cho từng phần riêng lẻ.

Sự khác biệt giữa các bộ lượng hóa tham lam, miễn cưỡng và sở hữu xâm nhập khi động cơ đưa ra lựa chọn về phần nào của chuỗi để khớp với và cách sửa đổi lựa chọn đó nếu lần đầu tiên nó không hoạt động. Luật như sau:

  • Một bộ định lượng tham lam bảo động cơ bắt đầu với toàn bộ chuỗi (hoặc ít nhất, tất cả chuỗi đã được khớp với các phần trước của biểu thức chính quy) và kiểm tra xem nó có khớp với biểu thức chính quy không. Nếu vậy, thật tuyệt; động cơ có thể tiếp tục với phần còn lại của regrec. Nếu không, nó sẽ thử lại, nhưng cắt bớt một ký tự (ký tự cuối cùng) khỏi phần của chuỗi cần kiểm tra. Nếu điều đó không hiệu quả, nó sẽ loại bỏ một ký tự khác, v.v. Vì vậy, một bộ định lượng tham lam sẽ kiểm tra các kết quả có thể theo thứ tự từ dài nhất đến ngắn nhất.

  • Một bộ định lượng miễn cưỡng bảo động cơ bắt đầu với đoạn ngắn nhất có thể của chuỗi. Nếu nó phù hợp, động cơ có thể tiếp tục; nếu không, nó sẽ thêm một ký tự vào phần của chuỗi đang được kiểm tra và thử điều đó, và cứ thế cho đến khi tìm thấy kết quả khớp hoặc toàn bộ chuỗi đã được sử dụng hết. Vì vậy, một bộ định lượng miễn cưỡng kiểm tra các kết quả khớp có thể theo thứ tự từ ngắn nhất đến dài nhất.

  • Bộ định lượng sở hữu giống như bộ định lượng tham lam trong lần thử đầu tiên: nó bảo động cơ bắt đầu bằng cách kiểm tra toàn bộ chuỗi. Sự khác biệt là nếu nó không hoạt động, bộ định lượng sở hữu báo cáo rằng trận đấu thất bại ngay lúc đó và ở đó. Công cụ không thay đổi phần của chuỗi được xem xét và nó không thực hiện thêm bất kỳ nỗ lực nào.

Đây là lý do tại sao kết quả của bộ định lượng sở hữu không thành công trong ví dụ của bạn: .*+nó được kiểm tra đối với toàn bộ chuỗi, nó khớp với nhau, nhưng sau đó công cụ tiếp tục tìm kiếm các ký tự bổ sung foosau đó - nhưng tất nhiên nó không tìm thấy chúng, bởi vì bạn đã ở cuối chuỗi. Nếu đó là một bộ định lượng tham lam, nó sẽ quay lại và thử tạo ra sự .*trùng khớp duy nhất với nhân vật kế tiếp, rồi đến nhân vật thứ ba đến nhân vật cuối cùng, rồi đến nhân vật thứ tư đến nhân vật cuối cùng, thành công bởi vì chỉ sau đó là có một foobên trái sau khi .*đã "ăn" phần trước của chuỗi.


1
Đó là một nguồn tuyệt vời. Tôi yêu sơ đồ máy nhà nước. :)
Regex Rookie

@Regex Rookie: rất vui vì bạn thích nó :) Tuy nhiên, sau khi xem qua trang web đó, tôi nghĩ rằng tôi nên làm rõ rằng mục đích của nó là để thúc đẩy việc triển khai thay thế một công cụ biểu thức chính quy. Thuật toán quay lui I (một phần) và các câu trả lời khác mô tả là cách chậm ; đó là một thuật toán hoàn toàn tách biệt với ý tưởng NFA / DFA được mô tả trong trang web. Quay lui chỉ đơn giản là dễ hiểu hơn, đó là lý do tại sao đó là cách thức biểu thức thường được giải thích cho người mới bắt đầu.
David Z

@David Zaslavsky: Giải thích tốt. Nhận xét của bạn trong ngoặc trong "Bộ định lượng tham lam bảo động cơ bắt đầu với toàn bộ chuỗi (hoặc ít nhất, tất cả các chuỗi chưa được khớp với các phần trước của biểu thức chính quy)" rất quan trọng. Họ cũng áp dụng cho các định lượng miễn cưỡng và sở hữu. Điều này làm cho lời giải thích của bạn tương thích với những gì xảy ra khi chúng ta thay đổi các mẫu ví dụ từ (". * Foo"; ". *? Foo"; và ". * + Foo") thành ("foo. *"; "Foo. *? "; và" foo. * + ").
John Bentley

Trên thực tế, xfooxxxxxxfoo không khớp. * Foo trong bình thường (ý nghĩa khoa học máy tính) của biểu thức chính quy. NFA sẽ là một trạng thái trong đó nó lặp lại với bất kỳ nhân vật nào và sau đó nó có thể nhảy đến foo. DFA sẽ là bản dịch đơn giản của NFA đó. Nó có thể được thực hiện trong 8 tiểu bang.
dùng4951

@JimThio yeah, vì đó không phải là định lượng sở hữu.
David Z

13

Dưới đây là cách tôi sử dụng các vị trí ô và chỉ mục (Xem sơ đồ ở đây để phân biệt một ô với chỉ mục).

Tham lam - Kết hợp càng nhiều càng tốt với bộ định lượng tham lam và toàn bộ biểu thức chính quy. Nếu không có kết quả khớp, quay lại trên bộ định lượng tham lam.

Chuỗi đầu vào: xfooxxxxxxfoo
Regex : . * Foo

Regex ở trên có hai phần:
(i) '. *' Và
(ii) 'foo'

Mỗi bước dưới đây sẽ phân tích hai phần. Nhận xét bổ sung cho trận đấu với 'Đạt' hoặc 'Thất bại' được giải thích trong niềng răng.

Bước 1:
(i). * = Xfooxxxxxxfoo - PASS ('. *' Là một bộ lượng hóa tham lam và sẽ sử dụng toàn bộ Chuỗi đầu vào)
(ii) foo = Không còn ký tự nào khớp với chỉ số 13 - FAIL
Match không thành công.

Bước 2:
(i). * = Xfooxxxxxxfo - PASS (Quay lại trên bộ định lượng tham lam '. *')
(Ii) foo = o -
Trận đấu FAIL thất bại.

Bước 3:
(i). * = Xfooxxxxxxf - PASS (Quay lại trên bộ định lượng tham lam '. *')
(Ii) foo = oo - FAIL
Trận đấu thất bại.

Bước 4:
(i). * = Xfooxxxxxx - PASS (Quay lại trên bộ định lượng tham lam '. *')
(Ii) foo = foo -
MATCH Báo cáo PASS

Kết quả: 1 trận đấu
Tôi đã tìm thấy văn bản "xfooxxxxxxfoo" bắt đầu từ chỉ số 0 và kết thúc ở chỉ số 13.

Bất đắc dĩ - Ghép càng ít càng tốt với bộ định lượng miễn cưỡng và khớp với toàn bộ biểu thức chính quy. nếu không có kết quả khớp, thêm ký tự vào bộ định lượng miễn cưỡng.

Chuỗi đầu vào: xfooxxxxxxfoo
Regex : . *? Foo

Regex ở trên có hai phần:
(i) '. *?' và
(ii) 'foo'

Bước 1 :
. *? = '' (để trống) - PASS (Ghép càng ít càng tốt với bộ định lượng miễn cưỡng '. *?'. Chỉ số 0 có '' là khớp.)
Foo = xfo - FAIL (Ô 0,1,2 - tức là chỉ số giữa 0 và 3)
Trận đấu thất bại.

Bước 2 :
. *? = x - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'. Ô 0 có 'x' là khớp.)
foo = foo - MATASS
Báo cáo MATCH

Bước 3 :
. *? = '' (để trống) - PASS (Ghép càng ít càng tốt với bộ định lượng miễn cưỡng '. *?'. Chỉ số 4 có '' là khớp.)
Foo = xxx - FAIL (Ô 4,5,6 - tức là chỉ số giữa 4 và 7)
Trận đấu thất bại.

Bước 4 :
. *? = x - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'. Ô 4.)
foo = xxx - FAIL (Ô 5,6,7 - tức là chỉ số giữa 5 và 8)
Không khớp.

Bước 5 :
. *? = xx - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'. Ô 4 đến 5.)
foo = xxx - FAIL (Ô 6,7,8 - tức là chỉ số từ 6 đến 9)
Không khớp.

Bước 6 :
. *? = xxx - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'. Ô 4 đến 6.)
foo = xxx - FAIL (Ô 7,8,9 - tức là chỉ số từ 7 đến 10)
Không khớp.

Bước 7 :
. *? = xxxx - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'.
Ô 4 đến 7.) foo = xxf - FAIL (Ô 8,9,10 - tức là chỉ số từ 8 đến 11)
Không .

Bước 8 :
. *? = xxxxx - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'.
Ô 4 đến 8.) foo = xfo - FAIL (Ô 9,10,11 - tức là chỉ số từ 9 đến 12)
Không .

Bước 9 :
. *? = xxxxxx - PASS (Thêm ký tự vào bộ định lượng miễn cưỡng '. *?'. Ô 4 đến 9.)
foo = foo - PASS (Ô 10,11,12 - tức là chỉ số từ 10 đến 13)
Báo cáo MATCH

Bước 10 :
. *? = '' (để trống) - PASS (Ghép càng ít càng tốt với bộ định lượng miễn cưỡng '. *?'. Chỉ số 13 trống.)
Foo = Không còn ký tự nào khớp - FAIL (Không có gì sau chỉ số 13 khớp)
trận đấu thất bại.

Kết quả: 2 trận đấu
Tôi tìm thấy văn bản "xfoo" bắt đầu từ chỉ số 0 và kết thúc ở chỉ số 4.
Tôi tìm thấy văn bản "xxxxxxfoo" bắt đầu từ chỉ mục 4 và kết thúc ở chỉ số 13.

Sở hữu - Ghép càng nhiều càng tốt với lượng tử sở hữu và khớp với toàn bộ regex. KHÔNG quay lại.

Chuỗi đầu vào: xfooxxxxxxfoo
Regex: . * + Foo

Regex ở trên có hai phần: '. * +' Và 'foo'.

Bước 1 :
. * + = Xfooxxxxxxfoo - PASS (Kết hợp càng nhiều càng tốt với bộ định lượng sở hữu '. *')
Foo = Không còn ký tự nào khớp - FAIL (Không có gì khớp với chỉ số 13) Không khớp
.

Lưu ý: Quay lại không được phép.

Kết quả: 0 trận đấu


1

Tham lam: "khớp chuỗi ký tự dài nhất có thể"

Bất đắc dĩ: "khớp với chuỗi ký tự ngắn nhất có thể"

Sở hữu: Điều này hơi lạ vì nó KHÔNG (trái ngược với sự tham lam và miễn cưỡng) cố gắng tìm một trận đấu cho toàn bộ regex.

Nhân tiện: Không có triển khai trình so khớp mẫu regex nào sẽ sử dụng quay lui. Tất cả các công cụ khớp mẫu ngoài đời thực đều cực kỳ nhanh - gần như không phụ thuộc vào độ phức tạp của biểu thức chính quy!


Theo như tôi biết thì hầu hết các triển khai sử dụng chung hiện nay đều có rất nhiều tính năng nên không thể không sử dụng quay lui. Vì vậy, trên lý thuyết, chúng nên cực kỳ chậm (theo cấp số nhân) đối với một số trường hợp. Nhưng đối với hầu hết các trường hợp đó, có các tối ưu hóa đặc biệt được tích hợp trong trình so khớp mẫu.
Robert

0

Định lượng tham lam liên quan đến khớp mẫu bằng cách sử dụng tất cả các ký tự không có giá trị còn lại của chuỗi trong một lần lặp. Các ký tự không có giá trị bắt đầu trong chuỗi hoạt động . Mỗi khi trận đấu không xảy ra, nhân vật ở cuối sẽ bị cách ly và kiểm tra lại được thực hiện.

Khi chỉ các điều kiện hàng đầu của mẫu biểu thức chính được thỏa mãn bởi chuỗi hoạt động, một nỗ lực được thực hiện để xác nhận các điều kiện còn lại chống lại việc kiểm dịch. Nếu xác thực này thành công, các ký tự trùng khớp trong kiểm dịch sẽ được xác thực và các ký tự không khớp còn lại vẫn không được xác định giá trị và sẽ được sử dụng khi quá trình bắt đầu lại trong lần lặp tiếp theo.

Dòng chảy của các ký tự là từ chuỗi hoạt động vào kiểm dịch. Hành vi kết quả là càng nhiều chuỗi ban đầu được đưa vào một trận đấu càng tốt.

Định lượng bất đắc dĩ hầu hết giống như phẩm chất tham lam ngoại trừ dòng chảy của các ký tự thì ngược lại - nghĩa là chúng bắt đầu trong kiểm dịch và chảy vào chuỗi hoạt động . Hành vi kết quả là càng ít trình tự ban đầu được đưa vào một trận đấu càng tốt.

Định lượng sở hữu không có kiểm dịch và bao gồm mọi thứ trong một chuỗi hoạt động cố định .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.