Biểu thức thường xuyên dừng lại ở trận đấu đầu tiên


531

Mẫu regex của tôi trông giống như

<xxxx location="file path/level1/level2" xxxx some="xxx">

Tôi chỉ quan tâm đến phần trong trích dẫn được chỉ định cho vị trí. Không nên dễ dàng như dưới đây mà không có công tắc tham lam?

/.*location="(.*)".*/

Có vẻ như không hoạt động.


Nguồn của bạn là gì, nó là HTML hay xml hay cái gì đó?
Oskar Kjellin

20
Tại sao đây là một wiki cộng đồng? Đó là một câu hỏi thực sự. Quá muộn rồi.
Ahmad Mageed

1
Bạn đang viết bằng ngôn ngữ nào Vui lòng không sử dụng regex cho XML. Có rất nhiều cách tốt hơn để phân tích cú pháp XML
Oskar Kjellin

3
Không phải nếu tất cả những gì bạn muốn là quét các thuộc tính đơn giản. Regex là phù hợp và nhanh hơn.
codenheim

Tôi sẽ nói rằng nếu bạn ví dụ mã c # thì tốt hơn nhiều là sử dụng linq cho việc này. Tôi nghi ngờ rằng sẽ tốt hơn nếu regex nếu bạn có một trình phân tích cú pháp tốt
Oskar Kjellin

Câu trả lời:


1096

Bạn cần làm cho biểu thức chính quy của bạn không tham lam, bởi vì theo mặc định, "(.*)"sẽ phù hợp với tất cả "file path/level1/level2" xxx some="xxx".

Thay vào đó, bạn có thể làm cho ngôi sao chấm của mình không tham lam, điều này sẽ khiến nó khớp với càng ít ký tự càng tốt:

/location="(.*?)"/

Thêm một ?trên một bộ định lượng ( ?, *hoặc +) làm cho nó không tham lam.


32
FWIW, trong trường hợp bạn sử dụng VIM, regex này cần có một chút khác biệt: thay vì .*?.\{-}cho một trận đấu không tham lam.
SooDesuNe

44
Cảm ơn Daniel. "Thêm một? Trên một bộ định lượng (?, * Hoặc +) làm cho nó không tham lam." là lời khuyên hữu ích cho tôi.
PhátHV

10
Các ? mô tả sự nhầm lẫn của tôi trong việc cố gắng để tìm ra điều này. Làm thế nào thích hợp.
Robbie Smith

1
Tôi tin rằng bạn có thể nói 'lười biếng' thay vì 'không tham lam'
Manticore

50

location="(.*)"sẽ khớp từ "sau location=cho đến" sau some="xxxtrừ khi bạn không tham lam. Vì vậy, bạn cần .*?(tức là làm cho nó không tham lam) hoặc tốt hơn thay thế .*bằng [^"]*.


3
[^ "] * có lẽ cũng nhanh hơn với hầu hết các công cụ regex vì không cần tra cứu mẫu sau mẫu hiện tại.
Jean Vincent

1
@Kip: Có lẽ bạn đúng, nhưng .*?ký hiệu này chung chung hơn[^"]*
Bondax

làm thế nào nếu tôi muốn bao gồm ký tự phân cách bằng [^ "] *
Frohlich

hoàn toàn không, nếu bạn không biết ^ và [] nghĩa là gì ở đây. Hầu hết mọi người sẽ hiểu. *
Vincent Gerris

31

Làm thế nào về

.*location="([^"]*)".*

Điều này tránh tìm kiếm không giới hạn với. * Và sẽ khớp chính xác với trích dẫn đầu tiên.


Do sự khác biệt trong grep , ở trên nên là mẫu ưa thích nếu tính di động là một mối quan tâm.
Josh Habdas

22

Sử dụng kết hợp không tham lam, nếu công cụ của bạn hỗ trợ nó. Thêm? bên trong chụp.

/location="(.*?)"/

11

Sử dụng các bộ định lượng Lazy ?không có cờ toàn cầu là câu trả lời.

Ví dụ,

nhập mô tả hình ảnh ở đây

Nếu bạn có cờ toàn cầu /gthì nó sẽ khớp với tất cả các trận đấu có độ dài thấp nhất như dưới đây. nhập mô tả hình ảnh ở đây


1

Bởi vì bạn đang sử dụng mô hình con được định lượng và được giải thích trong Perl Doc ,

Theo mặc định, một mô hình con được định lượng là " tham lam ", nghĩa là nó sẽ khớp nhiều lần nhất có thể (với một vị trí bắt đầu cụ thể) trong khi vẫn cho phép phần còn lại của mẫu khớp với nhau. Nếu bạn muốn nó khớp với số lần tối thiểu có thể, hãy làm theo bộ định lượng bằng dấu "?" . Lưu ý rằng ý nghĩa không thay đổi, chỉ là "sự tham lam":

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

Do đó, để cho phép mẫu được định lượng của bạn thực hiện khớp tối thiểu, hãy làm theo mẫu bằng cách ?:

/location="(.*?)"/

1

Đây là một cách khác.

Đây là một trong những bạn muốn. Đây là lười biếng[\s\S]*?

Mục đầu tiên: [\s\S]*?(?:location="[^"]*")[\s\S]* Thay thế bằng:$1

Giải thích : https://regex101.com/r/ZcqcUm/2


Để hoàn thiện, điều này nhận được cái cuối cùng. Thật là tham lam[\s\S]*

Mục cuối cùng:[\s\S]*(?:location="([^"]*)")[\s\S]* Thay thế bằng:$1

Giải thích : https://regex101.com/r/LXSPDp/3


Chỉ có 1 sự khác biệt giữa hai biểu thức chính quy này và đó là ?

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.