2013-05-30 35 views
16

Tôi có tên tập tin sau đó triển lãm mô hình này:Python regex split mà không chuỗi rỗng

000014_L_20111007T084734-20111008T023142.txt 
000014_U_20111007T084734-20111008T023142.txt 
... 

tôi muốn trích xuất hai phần tem thời gian giữa sau dấu gạch chân thứ hai '_' và trước '.txt'. Vì vậy, tôi đã sử dụng Python regex chuỗi phân chia như sau:

time_info = re.split('^[0-9]+_[LU]_|-|\.txt$', f) 

Nhưng điều này mang lại cho tôi hai chuỗi rỗng thêm trong danh sách trả về:

time_info=['', '20111007T084734', '20111008T023142', ''] 

Làm thế nào để tôi nhận được chỉ là thông tin tem hai lần? tức là tôi muốn:

time_info=['20111007T084734', '20111008T023142'] 

Trả lời

12

Đừng sử dụng re.split(), sử dụng số groups() meth od của regex Match/SRE_Match đối tượng.

>>> f = '000014_L_20111007T084734-20111008T023142.txt' 
>>> time_info = re.search(r'[LU]_(\w+)-(\w+)\.', f).groups() 
>>> time_info 
('20111007T084734', '20111008T023142') 

Bạn thậm chí có thể đặt tên cho nhóm chụp và lấy chúng trong một dict, mặc dù bạn sử dụng groupdict() hơn groups() cho điều đó. (Mẫu regex cho trường hợp này sẽ là một cái gì đó như r'[LU]_(?P<groupA>\w+)-(?P<groupB>\w+)\.')

+0

Đây là một giải pháp tốt đẹp. Cảm ơn. – tonga

+8

Đó là một sự xấu hổ 'chia' không có một tùy chọn" không có chuỗi rỗng ". – Elazar

+1

@Elazar Không thực sự, nó chỉ là vấn đề như thế nào 're.split()' được thực hiện và mục đích của nó là gì. Trong các trường hợp như thế này, sẽ có ý nghĩa hơn khi xây dựng một mẫu cho dữ liệu mong muốn hơn là tạo một mẫu cho phù hợp với mọi thứ không mong muốn. (Mặc dù 'str.split()' thực sự thả các chuỗi rỗng khi dấu tách không được chỉ định hoặc 'Không'.) – JAB

13

Tôi không phải chuyên gia về Python nhưng có thể bạn chỉ cần xóa các chuỗi trống khỏi danh sách của mình?

time_info = re.split('^[0-9]+_[LU]_|-|\.txt$', f) 
time_info = filter(None, str_list) 
+0

Tác phẩm này. Cảm ơn. Tôi tự hỏi nếu có bất kỳ giải pháp một pass nào sử dụng hàm 're.split()'. – tonga

+0

@tonga có, nhưng nó ít đẹp hơn: 'time_info = [x cho x trong re.split ('^ [0-9] + _ [LU] _ | - | \ .txt $', f) nếu x] ' – FraggaMuffin

+0

Vì filter() trả về một đối tượng lọc, bạn cần sử dụng list() sau:' time_info = list (filter (None, str_list)) ' –

2

Nếu timestamps luôn sau khi thứ hai _ sau đó bạn có thể sử dụng str.splitstr.strip:

>>> strs = "000014_L_20111007T084734-20111008T023142.txt" 
>>> strs.strip(".txt").split("_",2)[-1].split("-") 
['20111007T084734', '20111008T023142'] 
+0

Tôi thích làm những việc này mà không cần REs. Tôi không biết tại sao. – Elazar

+0

@Ashwini: Cảm ơn. Những công việc này. Nhưng làm thế nào tôi có thể làm điều này với phân chia regex? – tonga

+0

@Elazar Tôi nghi ngờ vì cụm từ thông dụng có thể khá khó hiểu nếu chúng được thực hiện sai hoặc quá phức tạp và không có nhận xét. Đôi khi một thao tác chuỗi được thực hiện với RE có thể dễ hiểu hơn khi được tạo thành một chuỗi các cuộc gọi hàm. (Trong trường hợp này, mặc dù, một loạt các hoạt động truy cập phần tử 'split()'/'strip()'/element là clunkier hơn là sử dụng RE sẽ là.) – JAB

1
>>> f='000014_L_20111007T084734-20111008T023142.txt' 
>>> f[10:-4].split('-') 
['0111007T084734', '20111008T023142'] 

hay, phần nào tổng quát hơn:

>>> f[f.rfind('_')+1:-4].split('-') 
['20111007T084734', '20111008T023142']