2009-09-09 71 views
7

Vì vậy, tôi cần phải nhận được giờ, phút và giây ra các mục như thế này:Giờ kết hợp/phút/giây trong biểu thức chính quy - một cách tốt hơn?

  • 04:43:12
  • 9.43.12
  • 1:00
  • 01,04

Hai giờ đầu tiên là phút, giây và giây. Tiếp theo là phút và giây. Hai giây cuối cùng chỉ là vài giây.

Và tôi đã đưa ra regexp này, mà làm việc ..:

\A(?<hours>\d{1,2})(?::|\.)(?<minutes>\d{1,2})(?::|\.)(?<seconds>\d{1,2})\z|\A(?<minutes>\d{1,2})(?::|\.)(?<seconds>\d{1,2})\z|\A(?<seconds>\d{1,2})\z 

Nhưng nó là xấu xí, và tôi muốn refactor nó xuống không được 3 thành ngữ khác nhau (chủ yếu là chỉ để học hỏi). Tôi đã thử điều này:

\A(?:(?<hours>\d{1,2})(?::|\.){0,1})(?:(?<minutes>\d{1,2})(?::|\.){0,1})(?:(?<seconds>\d{1,2}){0,1})\z 

Nhưng điều đó không hoạt động - phút và giây đôi khi bị làm hỏng. Não của tôi đang bị tổn thương, và tôi không thể hiểu được, những gì tôi đang làm sai.

+1

Đây KHÔNG phải là ngôn ngữ bất khả tri. Cú pháp của cụm từ thông dụng là khác nhau cho các ngôn ngữ khác nhau. –

Trả lời

10

Đề nghị của tôi:

(?:(?:(?<hh>\d{1,2})[:.])?(?<mm>\d{1,2})[:.])?(?<ss>\d{1,2}) 

cấu trúc:

(?:      # group 1 (non-capturing) 
    (?:     # group 2 (non-capturing) 
    (?<hh>\d{1,2})  #  hours 
    [:.]    #  delimiter 
)?     # end group 2, make optional 
    (?<mm>\d{1,2})  # minutes 
    [:.]     # delimiter 
)?      # end group 1, make optional 
(?<ss>\d{1,2})   # seconds (required) 

Nếu bạn muốn, bạn có thể quấn regex trong delimiters - ranh giới từ như \b hoặc chuỗi neo (^$).

EDIT: Suy nghĩ về điều đó, bạn có thể hạn chế hơn nữa để nắm bắt thời gian chỉ có ý nghĩa. Sử dụng

[0-5]?\d 

ở vị trí của

\d{1,2} 

để nắm bắt các giá trị giữa 0 và 59 chỉ, nơi thích hợp (giây và phút).

+0

Yêu các ví dụ có cấu trúc trong regexp ... – gnarf

+0

Tuyệt vời! Hoạt động tuyệt vời - và cũng thích định dạng. Nếu chỉ trình soạn thảo của tôi sẽ hỗ trợ điều đó, nó sẽ dễ dàng hơn để làm việc. – Kjensen

+0

Không phải là ký tự bình luận cho cụm từ thông dụng trong chế độ "bỏ qua khoảng trắng và cho phép nhận xét" chế độ '#' thay vì '//'? – Joey

2

Tôi đề xuất biểu thức sau.

^(((?<Hour>[0-9]{1,2})[.:])?(?<Minute>[0-9]{1,2})[.:])?(?<Second>[0-9]{2})$

này sẽ cho phép giờ chữ số duy nhất kết hợp với chữ số phút duy nhất như 3:7:21. Nếu điều này là không mong muốn, một sửa đổi nhỏ là bắt buộc.

^(((?<Hour>[0-9]{1,2})[.:](?=[0-9]{2}))?(?<Minute>[0-9]{1,2})[.:])?(?<Second>[0-9]{2})$

Các lookahead tích cực khẳng định (?=[0-9]{2}) trong biểu thức thứ hai giải quyết vấn đề này.

1

không có cách nào thực sự tốt cho điều này, vì nó thực sự phụ thuộc vào tình hình cụ thể của bạn phải làm gì khi không phải tất cả ba phần được chỉ định. Ví dụ, trong nhiều trường hợp, tôi có thể thích giải thích 3:30 là 3 giờ và 30 phút thay vì 3 phút và 30 giây. Nó không thể làm tổn thương được rõ ràng về điều đó, và làm cho nó dễ dàng để lấy được từ regex những gì các loại đầu vào có ý nghĩa.

Vì vậy, cá nhân tôi tin rằng regex đầu tiên không phải là xấu xí ở tất cả - nó có thể ít "ma thuật", nhưng nó dễ đọc hơn và dễ bảo trì hơn. Đảm bảo bạn và những người khác vẫn có thể đọc và thay đổi mã sau!

Nếu ngôn ngữ của bạn hỗ trợ nó, tôi sẽ sử dụng các regex mở rộng (với hỗ trợ khoảng trống và nhận xét) và chia nó thành ba dòng (hoặc 6 hoặc 9 nếu bạn đặt nhận xét trên một dòng riêng biệt). Điều đó sẽ không thay đổi regex, nhưng nó sẽ làm cho nó cảm thấy ít xấu xí cho chắc chắn.

+0

Điểm hợp lệ. Lý do tôi muốn làm cho nó tốt hơn là chủ yếu để học. – Kjensen

5

tôi đã không kiểm tra này, nhưng nó cũng làm việc:

^(?:(?:(?<hours>\d\d?)[:\.])?(?<minutes>\d\d?)[:\.])?(?<seconds>\d\d?)$ 

Edit:
Bây giờ tôi đã thử nghiệm nó và xác minh rằng nó hoạt động.:)

+0

Tác phẩm này sẽ ghi lại 3: 7: 21 những gì có thể hoặc không được dự kiến ​​là 3:07:21. Và bằng cách này, không cần phải thoát khỏi dấu chấm trong các nhóm nhân vật. (Hoặc tôi có sai không? Có thực hiện regex yêu cầu điều này không?) –

+0

Dấu gạch chéo ngược trên dấu chấm trong một lớp ký tự là không cần thiết. Cho phép 3: 7: 21 trong 3:07:21 có lẽ là một ví dụ về 'hào phóng trong những gì bạn chấp nhận'. –

+0

Tôi có xu hướng thoát khỏi một số nhân vật không hoàn toàn cần trốn thoát. Ngay cả khi lớp Regex không cần nó để hiểu nó, tôi có thể. :) – Guffa

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