2012-03-16 38 views
6

Cách dễ nhất để giải thích đây là một ví dụ: Tôi có chuỗi này: 'Documents/src/Scripts/temp' Mà tôi biết làm thế nào để phân chia hai cách khác nhau:Python Regex Chia Keeps Tách mẫu nhân vật

re.split('/', 'Docs/src/Scripts/temp') -> ['Docs', 'src', 'Scripts', 'temp'] 

re.split('(/)', 'Docs/src/Scripts/temp') -> ['Docs', '/', 'src', '/', 'Scripts', '/', 'temp'] 

Có cách nào để tách bằng dấu gạch chéo, nhưng giữ phần gạch chéo của các từ không? Ví dụ: tôi muốn chuỗi ở trên trông như sau:

['Docs/', '/src/', '/Scripts/', '/temp'] 

Bất kỳ trợ giúp nào sẽ được đánh giá cao!

+0

Đó là 're.split ('(/)', ...) ', không phải' re.split (('/'), ...) '. –

Trả lời

8

Thú vị câu hỏi, tôi sẽ đề nghị làm một cái gì đó như thế này:

>>> 'Docs/src/Scripts/temp'.replace('/', '/\x00/').split('\x00') 
['Docs/', '/src/', '/Scripts/', '/temp'] 

Ý tưởng ở đây là lần đầu tiên thay thế tất cả / ký tự bởi hai / ký tự ngăn cách bởi một nhân vật đặc biệt mà sẽ không phải là một phần của bản gốc chuỗi. Tôi đã sử dụng một byte rỗng ('\x00'), nhưng bạn có thể thay đổi điều này thành một cái gì đó khác, sau đó cuối cùng chia thành nhân vật đặc biệt đó. Regex không thực sự tuyệt vời ở đây bởi vì bạn không thể chia nhỏ trên các trận đấu có độ dài bằng không, và re.findall() không tìm thấy các kết quả trùng lặp, vì vậy bạn có khả năng cần phải thực hiện một số lượt vượt qua chuỗi.

Ngoài ra, re.split('/', s) sẽ thực hiện tương tự như s.split('/'), nhưng thứ hai hiệu quả hơn.

+0

Cảm ơn bạn đã trả lời! – user1274774

+1

Thực hiện việc chia nhỏ và tham gia giống như 'Documents/src/Scripts/temp'.replace ('/','/\ x00/') ' –

+0

@gnibbler - Silly me, cảm ơn điều đó sạch hơn nhiều! Đã thay đổi câu trả lời của tôi để sử dụng câu trả lời đó. –

1

Tôi không chắc chắn có cách dễ dàng để thực hiện việc này. Đây là điều tốt nhất tôi có thể đưa ra ...

import re 

lSplit = re.split('/', 'Docs/src/Scripts/temp') 
print [lSplit[0]+'/'] + ['/'+x+'/' for x in lSplit][1:-1] + ['/'+lSplit[len(lSplit)-1]] 

Loại lộn xộn, nhưng nó làm những gì bạn muốn.

+0

Tại sao bạn cần biểu thức chính quy khi bạn chỉ chia nhỏ một ký tự? – hop

+0

Bạn không. Bạn có thể sử dụng str.split() nếu bạn muốn. Câu trả lời của F.J tốt hơn tôi. – b10hazard

3

1) Bạn không cần phải biểu thức thông thường để phân chia trên một nhân vật cố định duy nhất:

>>> 'Docs/src/Scripts/temp'.split('/') 

[ 'Documents', 'src', 'Scripts', 'tạm thời']

2) Xem xét sử dụng phương pháp này:

import os.path 

def components(path): 
    start = 0 
    for end, c in enumerate(path): 
     if c == os.path.sep: 
      yield path[start:end+1] 
      start = end 
    yield path[start:] 

nó không dựa vào thủ đoạn thông minh như split-gia-chia, mà làm cho nó nhiều hơn nữa có thể đọc được, theo ý kiến ​​của tôi.

2

Nếu bạn không nhấn mạnh vào việc có dấu gạch chéo trên cả hai mặt, nó thực sự khá đơn giản:

>>> re.findall(r"([^/]*/)", 'Docs/src/Scripts/temp') 
['Docs/', 'src/', 'Scripts/'] 

Cả re cũng không phân chia được thực sự cắt ra cho chuỗi chồng chéo, vì vậy nếu đó là những gì bạn thực sự muốn, tôi 'd chỉ cần thêm dấu gạch chéo vào đầu mỗi kết quả ngoại trừ kết quả đầu tiên.

5

Một giải pháp mà không split() nhưng với lookaheads:

>>> s = 'Docs/src/Scripts/temp' 
>>> r = re.compile(r"(?=((?:^|/)[^/]*/?))") 
>>> r.findall(s) 
['Docs/', '/src/', '/Scripts/', '/temp'] 

Giải thích:

(?=  # Assert that it's possible to match... 
(  # and capture... 
    (?:^|/) # the start of the string or a slash 
    [^/]* # any number of non-slash characters 
    /?  # and (optionally) an ending slash. 
)   # End of capturing group 
)   # End of lookahead 

Từ một sự khẳng định lookahead đang cố gắng ở mọi vị trí trong chuỗi và không tiêu thụ bất kỳ ký tự, nó không có vấn đề với các trận trùng lặp.

+0

Ha, tôi đã làm việc câu hỏi này chỉ để cho vui và đi ra với cùng một regex như bạn, nhân vật cho nhân vật! (Ngoại trừ tôi đã có một '+', nơi bạn có một '*') :) +1 – zx81

2

Hãy thử về điều này:

re.split(r'(/)', 'Docs/src/Scripts/temp') 

Từ tài liệu python của

re.split (pattern, chuỗi, maxsplit = 0, cờ = 0)

Chia chuỗi bởi lần xuất hiện của mẫu. Nếu chụp dấu ngoặc đơn được sử dụng theo mẫu, thì văn bản của tất cả các nhóm trong mẫu cũng được trả về như một phần của danh sách kết quả. Nếu maxsplit không đồng nhất, tại hầu hết các phần tách maxsplit, xảy ra và phần còn lại của chuỗi được trả về thành phần cuối cùng của danh sách. (Không tương thích lưu ý:. Trong phiên bản gốc Python 1.5 , maxsplit đã bị bỏ qua này đã được cố định trong các phiên bản sau này.)

+0

Xin lỗi, chỉ cần nhầm lẫn. –

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