2012-09-26 59 views
5

Tôi đang viết một tập lệnh Python chấp nhận đường dẫn tệp dưới dạng chuỗi, phân tích cú pháp, nối thêm tên lệnh và xây dựng danh sách, sau đó được chuyển đến subprocess.Popen() để thực thi. Kịch bản này là để xử lý cả hai đường dẫn tập tin Unix và Windows, và cuối cùng nên chạy trên cả hai hệ thống.Làm thế nào để ngăn chặn tự động thoát các ký tự đặc biệt trong Python

Khi tôi chạy điều này trong Unix, nếu tôi cung cấp đường dẫn Windows vô tình chứa ký tự thoát (ví dụ: \Users\Administrator\bin), Python sẽ giải thích ký tự không gian sau \b. Tôi muốn ngăn điều đó xảy ra.

Theo như tôi biết, không có hàm hoặc phương thức nào biểu thị biến chuỗi dưới dạng chuỗi thô. Công cụ sửa đổi 'r' chỉ hoạt động đối với các hằng số chuỗi.

Cho đến nay, gần nhất tôi đã có thể có được là thế này:

winpath = "C:\Users\Administrator\bin" 
winpath = winpath.replace('\b','\\b') 
winpathlist = winpath.split('\\') 

Tại thời điểm này, winpathlist nên chứa ['C:','Users','Administrator','bin'], không ['C','Users','Administrator\x08in'].

tôi có thể thêm các cuộc gọi bổ sung cho winpath.replace() để xử lý thoát khác tôi có thể nhận được - \a, \f, \n, \r, \t, \v - nhưng không \x.

Có cách nào khác để làm điều này không?

+5

Làm thế nào để bạn nhận được giá trị vào chuỗi? Python không nên coi \ b là một lối thoát trừ khi nó nằm trong chuỗi ký tự, hoặc được đưa vào chuỗi như là một lối thoát để bắt đầu. (Ngoài ra, dấu gạch chéo chuyển tiếp hoạt động tốt.) – geoffspear

+0

@Wooble: Ngay bây giờ, nó đến qua doctest. >>> myCommandObject.setExcecutablePath ('C: \ Program Files \ cygwin \ cdrive \ bin') nơi myCommandObject chứa tên lệnh (ví dụ: 'ps'), đường dẫn và danh sách đối số. Thay đổi dấu gạch chéo từ dấu gạch chéo ngược sang dấu gạch chéo không phải là một tùy chọn; khách hàng của tôi đã tuyên bố rõ ràng rằng đây là những gì anh ta muốn. – poltr1

+0

Như tôi đã nói, r chỉ hoạt động đối với các chuỗi ký tự; nó không hoạt động đối với các biến chuỗi. Tôi nhìn vào r hàng đầu như một kluge. Dù sao, đây là tài liệu (hoặc một phần của nó): >>> myCommand.setExecutablePath ('C: \ Program Files \ cygwin \ cdrive \ bin') >>> myCommandList = myCommand.getLaunchList() >> > myCommandList ['C: \\\\ Chương trình tập tin \\\ cygwin \\\ cdrive \\\\ \\\\', '-e', '-f'] >>> myCommandList [0] .split ("\\\\") ['C:', 'Tập tin chương trình', 'cygwin', 'cdrive', 'bin', 'ps'] Tôi không còn nhận được bất kỳ lỗi, bây giờ tôi đã thêm cuộc gọi để thay thế. – poltr1

Trả lời

6

Nếu winpath của bạn được mã hóa cứng, bạn có thể muốn sử dụng r trước khi chuỗi của bạn biểu thị nó là "raw string".

winpath = r"C:\Users\Administrator\bin" 

Nếu winpath không thể hardcoded, bạn có thể cố gắng tạo ra một chuỗi mới như:

escaped_winpath = "%r" % winpath 

(mà chỉ là repr(winpath), và sẽ không thực sự giúp bạn, như repr("\bin") là ...)

Giải pháp sẽ là xây dựng lại chuỗi từ đầu: bạn có thể tìm thấy ví dụ về hàm tại that link, nhưng ý tưởng chung là:

escape_dict={'\a':r'\a', 
      '\b':r'\b', 
      '\c':r'\c', 
      '\f':r'\f', 
      '\n':r'\n', 
      '\r':r'\r', 
      '\t':r'\t', 
      '\v':r'\v', 
      '\'':r'\'', 
      '\"':r'\"'} 

def raw(text): 
    """Returns a raw string representation of text""" 
    new_string='' 
    for char in text: 
     try: 
      new_string += escape_dict[char] 
     except KeyError: 
      new_string += char 
    return new_string 

và bây giờ, raw("\bin") mang đến cho bạn "\\bin" (và không "\\x08in") ...

+0

Tôi không quen thuộc với repr(). Có trong phiên bản 2.6 không? Tôi thích ý tưởng này, và sẽ tiếp tục với điều này trong trường hợp tôi cần nó trong tương lai. Theo yêu cầu của khách hàng của tôi, tôi đã rút ra các cuộc gọi để thay thế(). Thay vào đó, ông đề xuất rằng tôi di chuyển kiểm tra đường dẫn Windows ra khỏi tài liệu và vào một tệp riêng biệt. Cám ơn vì sự gợi ý. – poltr1

4

Bạn có thể tạo một chuỗi nguyên bởi prepending r vào chuỗi ký hiệu đen

r"hello\nworld" 

trở thành

"hello\\nworld" 

Bạn có thể đọc thêm một số chi tiết here

+0

Phủ định. Nếu tôi đặt vào r trong chuỗi doctest như bạn đề nghị, nó sẽ trở thành một phần của chuỗi. – poltr1

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