2008-10-24 33 views
7

Tôi có một chuỗi đó là như thế này:chuỗi Splitting trong python

đây là [thử nghiệm khung] "và trích dẫn test"

Tôi đang cố gắng để viết một cái gì đó bằng Python để tách nó ra bởi không gian trong khi bỏ qua dấu cách trong dấu ngoặc vuông và dấu ngoặc kép. Kết quả tôi đang tìm kiếm là:

[ 'này', 'là', 'kiểm tra khung', 'và trích test']

+1

Làm dấu ngoặc? Có thể có dấu ngoặc chưa khớp trong dấu ngoặc kép không? Điều gì về dấu ngoặc kép chưa? Đầu ra chính xác cho những điều sau đây: [[ngoặc vuông] kiểm tra] "bra [trong dấu ngoặc kép" "ket] trong dấu ngoặc kép" [quote "trong ngoặc vuông]"] –

Trả lời

8

Dưới đây là một giải pháp đơn giản mà làm việc với đầu vào thử nghiệm của bạn:

import re 
re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+',s) 

này sẽ trở lại bất kỳ mã phù hợp với một trong hai

  • một khung mở tiếp theo không hoặc nhiều ký tự phi cận khung theo sau là một khung gần,
  • một đôi quote tiếp theo không hoặc nhiều ký tự không quote theo sau là một báo giá,
  • bất kỳ nhóm các ký tự không phải khoảng trắng

này hoạt động với ví dụ của bạn, nhưng có thể thất bại đối với nhiều chuỗi thực thế giới bạn có thể gặp phải. Ví dụ, bạn không nói những gì bạn mong đợi với dấu ngoặc đơn hoặc dấu ngoặc kép không cân bằng hoặc cách bạn muốn dấu nháy đơn hoặc ký tự thoát hoạt động. Tuy nhiên, đối với các trường hợp đơn giản, điều trên có thể đủ tốt.

+0

Điều này để lại dấu ngoặc kép và dấu ngoặc và. Đó không phải là chính xác những gì đã được yêu cầu. –

1

Dưới đây là một trình phân tích cú pháp đơn giản (được kiểm tra dựa vào đầu vào ví dụ của bạn) giới thiệu mẫu thiết kế của Nhà nước.

Trong thế giới thực, bạn có thể muốn xây dựng một trình phân tích cú pháp thực bằng cách sử dụng một cái gì đó như PLY.

class SimpleParser(object): 

    def __init__(self): 
     self.mode = None 
     self.result = None 

    def parse(self, text): 
     self.initial_mode() 
     self.result = [] 
     for word in text.split(' '): 
      self.mode.handle_word(word) 
     return self.result 

    def initial_mode(self): 
     self.mode = InitialMode(self) 

    def bracket_mode(self): 
     self.mode = BracketMode(self) 

    def quote_mode(self): 
     self.mode = QuoteMode(self) 


class InitialMode(object): 

    def __init__(self, parser): 
     self.parser = parser 

    def handle_word(self, word): 
     if word.startswith('['): 
      self.parser.bracket_mode() 
      self.parser.mode.handle_word(word[1:]) 
     elif word.startswith('"'): 
      self.parser.quote_mode() 
      self.parser.mode.handle_word(word[1:]) 
     else: 
      self.parser.result.append(word) 


class BlockMode(object): 

    end_marker = None 

    def __init__(self, parser): 
     self.parser = parser 
     self.result = [] 

    def handle_word(self, word): 
     if word.endswith(self.end_marker): 
      self.result.append(word[:-1]) 
      self.parser.result.append(' '.join(self.result)) 
      self.parser.initial_mode() 
     else: 
      self.result.append(word) 

class BracketMode(BlockMode): 
    end_marker = ']' 

class QuoteMode(BlockMode): 
    end_marker = '"' 
-2

Chỉ hoạt động để báo giá.

rrr = [] 
qqq = s.split('\"') 
[ rrr.extend(qqq[x].split(), [ qqq[x] ])[ x%2]) for x in range(len(qqq))] 
print rrr 
0

Dưới đây là một cách tiếp cận thủ tục hơn:

#!/usr/bin/env python 

a = 'this is [bracket test] "and quotes test "' 

words = a.split() 
wordlist = [] 

while True: 
    try: 
     word = words.pop(0) 
    except IndexError: 
     break 
    if word[0] in '"[': 
     buildlist = [word[1:]] 
     while True: 
      try: 
       word = words.pop(0) 
      except IndexError: 
       break 
      if word[-1] in '"]': 
       buildlist.append(word[:-1]) 
       break 
      buildlist.append(word) 
     wordlist.append(' '.join(buildlist)) 
    else: 
     wordlist.append(word) 

print wordlist 
5

Để hoàn Bryan bưu chính, phù hợp chính xác câu trả lời:

>>> import re 
>>> txt = 'this is [bracket test] "and quotes test "' 
>>> [x[1:-1] if x[0] in '["' else x for x in re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+', txt)] 
['this', 'is', 'bracket test', 'and quotes test '] 

Đừng hiểu lầm toàn bộ cú pháp sử dụng: Đây không phải là nhiều các số liệu thống kê trên một dòng duy nhất nhưng một chỉ số chức năng đơn (nhiều lỗi hơn).

0

Vâng, tôi đã gặp sự cố này khá nhiều lần, điều này đã dẫn tôi viết hệ thống của riêng tôi để phân tích cú pháp bất kỳ loại cú pháp nào.

Kết quả của việc này có thể được tìm thấy here; lưu ý rằng điều này có thể là quá mức cần thiết, và nó sẽ cung cấp cho bạn một cái gì đó cho phép bạn phân tích cú pháp câu lệnh với cả dấu ngoặc và dấu ngoặc đơn, dấu nháy đơn và kép, như lồng nhau như bạn muốn. Ví dụ, bạn có thể phân tích một cái gì đó như thế này (ví dụ viết bằng Common Lisp):

(defun hello_world (&optional (text "Hello, World!")) 
    (format t text)) 

Bạn có thể sử dụng làm tổ, khung (vuông) và dấu ngoặc đơn (tròn), đơn và chuỗi dụng dấu ngoặc kép, và nó rất có thể mở rộng.

Ý tưởng về cơ bản là việc triển khai có thể cấu hình của Máy hữu hạn nhà nước, tạo nên một cây cú pháp trừu tượng theo từng ký tự. Tôi khuyên bạn nên xem mã nguồn (xem liên kết ở trên) để bạn có thể có ý tưởng về cách thực hiện. Nó có khả năng thông qua các biểu thức thông thường, nhưng hãy thử viết một hệ thống bằng cách sử dụng REs và sau đó cố gắng mở rộng nó (hoặc thậm chí hiểu nó) sau này.

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