Regex để khớp với ký tự cuối dòng hoặc “/” của URL


80

Tôi có một URL và tôi đang cố gắng khớp nó với một biểu thức chính quy để kéo ra một số nhóm. Vấn đề tôi đang gặp phải là URL có thể kết thúc hoặc tiếp tục bằng "/" và văn bản URL khác. Tôi muốn khớp các URL như thế này:

Nhưng không khớp với một cái gì đó như thế này:

Vì vậy, tôi nghĩ đặt cược tốt nhất của tôi là một cái gì đó như thế này:

/(.+)/(\d{4}-\d{2}-\d{2})-(\d+)[/$]

trong đó lớp ký tự ở cuối chứa "/" hoặc cuối dòng. Mặc dù vậy, lớp nhân vật dường như không hài lòng với "$" trong đó. Làm cách nào để tôi có thể phân biệt tốt nhất giữa các URL này trong khi vẫn lấy lại các nhóm chính xác?

Câu trả lời:


41
/(.+)/(\d{4}-\d{2}-\d{2})-(\d+)(/.*)?$

Nhóm bắt đầu tiên (.+)

.+ khớp với bất kỳ ký tự nào (ngoại trừ ký tự kết thúc dòng)

  • + Bộ định lượng - Đối sánh giữa một lầnkhông giới hạn , nhiều lần nhất có thể, trả lại khi cần thiết (tham lam)

Nhóm chụp thứ 2 (\d{4}-\d{2}-\d{2})

\d{4}khớp với một chữ số (bằng [0-9])

  • {4} Bộ định lượng - Đối sánh chính xác 4 lần

-khớp với ký tự theo -nghĩa đen (phân biệt chữ hoa chữ thường)

\d{2}khớp với một chữ số (bằng [0-9])

  • {2} Bộ định lượng - Đối sánh chính xác 2 lần

-khớp với ký tự theo -nghĩa đen (phân biệt chữ hoa chữ thường)

\d{2}khớp với một chữ số (bằng [0-9])

  • {2} Bộ định lượng - Đối sánh chính xác 2 lần

-khớp với ký tự theo -nghĩa đen (phân biệt chữ hoa chữ thường)

Nhóm chụp thứ 3 (\d+)

\d+khớp với một chữ số (bằng [0-9])

  • + Bộ định lượng - Đối sánh giữa một lầnkhông giới hạn , nhiều lần nhất có thể, trả lại khi cần thiết (tham lam)

Nhóm chụp thứ 4 (.*)?

? Bộ định lượng - Đối sánh giữa khôngmột lần, nhiều lần nhất có thể, trả lại nếu cần (tham lam)

.*khớp với bất kỳ ký tự nào (ngoại trừ ký tự kết thúc dòng)

  • * Bộ định lượng - Đối sánh giữa khôngkhông giới hạn thời gian, nhiều lần nhất có thể, trả lại khi cần thiết (tham lam)

$ khẳng định vị trí ở cuối chuỗi


126

Để khớp một trong hai / hoặc cuối nội dung, hãy sử dụng (/|\z)

Điều này chỉ áp dụng nếu bạn không sử dụng đối sánh nhiều dòng (tức là bạn đang đối sánh một URL, không phải danh sách URL được phân tách bằng dòng mới).


Để thực hiện điều đó với một phiên bản cập nhật của những gì bạn có:

/(\S+?)/(\d{4}-\d{2}-\d{2})-(\d+)(/|\z)

Lưu ý rằng tôi đã thay đổi phần bắt đầu thành một kết hợp không tham lam cho không có khoảng trắng ( \S+?) thay vì so khớp bất kỳ thứ gì và mọi thứ ( .*)


6
Làm thế nào để tôi cho bạn thêm điểm;) Cảm ơn vì điều này. Chỉ với tài liệu (/ | \ A) sẽ khớp với dấu gạch chéo lên phía trước hoặc phần đầu của chuỗi.
Senica Gonzalez

Xin chúc mừng huy hiệu Câu trả lời vàng mới của bạn;) - Chỉ cần nhận ra rằng tôi đã đẩy bạn lên 100!
random_user_name

63

Bây giờ bạn đã có một vài regexes sẽ làm những gì bạn muốn, vì vậy nó được bảo hiểm đầy đủ.

Điều gì đã không được đề cập là lý do nỗ lực của bạn sẽ không làm việc: Bên trong một lớp nhân vật, $(cũng như ^, ./) không có ý nghĩa đặc biệt, vì vậy [/$]trận đấu hoặc một chữ /hay một chữ $chứ không phải là chấm dứt regex ( /) hoặc khớp end-of-line ( $).


8
Đây là một cái gì đó thường xuyên bị lãng quên và không được đề cập đến trong tài liệu regex.
Steve Dunn

6
Lưu ý rằng ^ có thể có ý nghĩa đặc biệt trong một lớp ký tự. Nếu nó là ký tự đầu tiên trong lớp, nó trở thành một lớp phủ định sẽ khớp với bất kỳ thứ gì ngoại trừ các ký tự khác. Ví dụ: để so khớp bất kỳ thứ gì ngoại trừ a hoặc b, bạn có thể sử dụng [^ ab]. Để bao gồm một ký tự ^, chỉ cần đảm bảo rằng nó không phải là chữ cái đầu tiên, vì vậy để khớp với a, b hoặc ^, bạn sẽ sử dụng [ab ^].
David Mason

18

Trong Ruby và Bash, bạn có thể sử dụng $bên trong dấu ngoặc đơn.

/(\S+?)/(\d{4}-\d{2}-\d{2})-(\d+)(/|$)

(Giải pháp này tương tự như Pete Boughton, nhưng giữ nguyên cách sử dụng $, có nghĩa là cuối dòng, thay vì sử dụng \z, có nghĩa là cuối chuỗi.)


2
PHP cũng vậy từ những gì tôi có thể nói. Tôi thấy không có lý do gì tại sao $không thể được sử dụng trong dấu ngoặc đơn ()trong bất kỳ triển khai nào. Đó là dấu ngoặc []làm cho nó theo nghĩa đen.
Joel Mellon

3
$hoạt động theo cách này trong javascript, ngược lại \zthì không (Chrome 48, Firefox 43, IE9).
Vsevolod Golovanov

1
Đây là lựa chọn thẳng thắn nhất. Khớp dấu gạch chéo hoặc cuối dòng. Nó thậm chí phù hợp với tiêu đề của câu hỏi này!
Brett Donald
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.