2009-04-16 18 views
5

Tôi là một tổng noob python vì vậy hãy chịu với tôi. Tôi muốn có python quét một trang html và thay thế các thể hiện của các thực thể Microsoft Word bằng một cái gì đó tương thích UTF-8.Một số câu hỏi Python cơ bản

Câu hỏi của tôi là, làm thế nào để bạn làm điều đó trong Python (Tôi đã google này nhưng chưa tìm thấy một câu trả lời rõ ràng cho đến nay)? Tôi muốn nhúng ngón chân vào vùng biển Python vì vậy tôi hình một thứ đơn giản như thế này là một nơi tốt để bắt đầu. Có vẻ như rằng tôi sẽ cần phải:

  1. tải văn bản dán từ MS Word vào một biến
  2. chạy một số loại thay thế chức năng về nội dung
  3. đầu ra nó

Trong PHP tôi sẽ làm như sau:

$test = $_POST['pasted_from_Word']; //for example “Going Mobile” 

function defangWord($string) 
{ 
    $search = array(
     (chr(0xe2) . chr(0x80) . chr(0x98)), 
     (chr(0xe2) . chr(0x80) . chr(0x99)), 
     (chr(0xe2) . chr(0x80) . chr(0x9c)), 
     (chr(0xe2) . chr(0x80) . chr(0x9d)), 
     (chr(0xe2) . chr(0x80) . chr(0x93)), 
     (chr(0xe2) . chr(0x80) . chr(0x94)), 
     (chr(0x2d)) 
    ); 

    $replace = array(
     "‘", 
     "’", 
     "“", 
     "”", 
     "–", 
     "—", 
     "–" 
    ); 

    return str_replace($search, $replace, $string); 
} 

echo defangWord($test); 

Bạn sẽ làm điều đó bằng Python bằng cách nào?

EDIT: Hmmm, ok bỏ qua sự nhầm lẫn của tôi về UTF-8 và các thực thể cho thời điểm này. Dữ liệu nhập chứa văn bản được dán từ MS Word. Những thứ như dấu ngoặc kép được hiển thị dưới dạng biểu tượng kỳ lạ. Các hàm PHP khác nhau mà tôi đã sử dụng để thử và khắc phục nó không mang lại cho tôi kết quả mong muốn. Bằng cách xem những biểu tượng kỳ lạ trong một trình soạn thảo hex tôi thấy rằng chúng tương ứng với các ký hiệu tôi đã sử dụng ở trên (0xe2, 0x80 vv). Vì vậy, tôi chỉ đơn giản là hoán đổi các ký tự kỳ quặc với các thực thể HTML. Vì vậy, nếu bit tôi đã ở trên đã IS UTF-8, những gì đang được dán trong từ MS Word đó là gây ra các biểu tượng kỳ lạ?

EDIT2: Vì vậy, tôi đặt ra để tìm hiểu một chút về Python và thấy rằng tôi không thực sự hiểu mã hóa. Vấn đề tôi đã cố gắng giải quyết có thể được xử lý đơn giản bằng cách mã hóa không nhất quán từ đầu đến cuối. Nếu biểu mẫu đầu vào là UTF-8, cơ sở dữ liệu lưu trữ đầu vào là UTF-8 và trang kết quả đầu ra là UTF-8 ... việc dán từ Word hoạt động tốt. Không có chức năng đặc biệt cần thiết. Bây giờ, về việc học một chút Python ...

+1

+1: "defangWord()" ... Tôi thích nó! :-) –

Trả lời

20

Trước hết, đó không phải là các thực thể Microsoft Word — chúng UTF-8. Bạn đang chuyển đổi chúng thành các thực thể HTML.

Cách Pythonic để viết một cái gì đó như:

chr(0xe2) . chr(0x80) . chr(0x98) 

sẽ là:

'\xe2\x80\x98' 

Nhưng Python đã có tích hợp chức năng cho các loại chuyển đổi bạn muốn làm:

def defang(string): 
    return string.decode('utf-8').encode('ascii', 'xmlcharrefreplace') 

Điều này sẽ thay thế mã UTF-8 trong chuỗi cho các ký tự như với các thực thể số như “.

Nếu bạn muốn thay thế những thực thể số với những người thân tên là nếu có thể:

import re 
from htmlentitydefs import codepoint2name 

def convert_match_to_named(match): 
    num = int(match.group(1)) 
    if num in codepoint2name: 
     return "&%s;" % codepoint2name[num] 
    else: 
     return match.group(0) 

def defang_named(string): 
    return re.sub('&#(\d+);', convert_match_to_named, defang(string)) 

Và sử dụng nó như vậy:

>>> defang_named('\xe2\x80\x9cHello, world!\xe2\x80\x9d') 
'“Hello, world!”' 

Để hoàn thành câu trả lời, các mã tương đương với ví dụ của bạn để xử lý tệp sẽ trông giống như sau:

# in Python, it's common to operate a line at a time on a file instead of 
# reading the entire thing into memory 

my_file = open("test100.html") 
for line in my_file: 
    print defang_named(line) 
my_file.close() 

Lưu ý rằng câu trả lời này được nhắm mục tiêu tại Python 2.5; tình hình Unicode là khác nhau đáng kể cho Python 3+.

Tôi cũng đồng ý với nhận xét của bobince bên dưới: nếu bạn chỉ có thể giữ văn bản ở định dạng UTF-8 và gửi văn bản với loại nội dung và bộ ký tự chính xác, hãy làm điều đó; nếu bạn cần nó trong ASCII, sau đó gắn bó với các thực thể số — thực sự không cần phải sử dụng các tên được đặt tên.

+0

+1 cho xmlcharrefreplace - không cần cho các thực thể có tên HTML ngày nay thực sự. Nhưng thực sự, để lại UTF-8 một mình, thông minh báo giá còn nguyên vẹn. Chừng nào bạn còn phân phối nó với tiêu đề/thẻ meta chính xác 'charset' thì không có vấn đề gì. – bobince

+0

+1 để chỉ ra rằng các thực thể là UTF-8 và không phải là một số kỳ lạ MS ;-) (và cho một câu trả lời tốt bằng văn bản tổng thể, quá) –

+0

Tôi đang bối rối. Tài liệu tôi đang nhập trong ví dụ có đầy đủ các ký hiệu lạ tương ứng với các dấu ngoặc nhọn MS Word. Nếu tôi thả chúng thẳng vào một trang có mã hóa UTF-8, tôi sẽ nhận được các ký hiệu lạ. Nếu tôi chuyển đổi chúng bằng cách sử dụng mã ví dụ của chúng, chúng sẽ hiển thị tốt. Vì vậy, chúng là gì trước khi tôi chuyển đổi? – Stuart

3

Mã Python có cùng đường viền.

Chỉ cần thay thế tất cả các PHP-isms bằng Python-isms.

Bắt đầu bằng cách tạo đối tượng File. Kết quả của tệp.read() là đối tượng string. Các chuỗi có hoạt động "thay thế".

2

Đặt cược tốt nhất của bạn để làm sạch Word HTML đang sử dụng HTML Tidy có chế độ chỉ dành cho điều đó. Có a few Python wrappers bạn có thể sử dụng nếu bạn cần làm điều đó theo chương trình.

1

Như S.Lott cho biết, mã Python sẽ rất, rất giống nhau — khác biệt duy nhất về bản chất là các lời gọi/báo cáo chức năng.

Tôi không nghĩ rằng Python có một tương đương trực tiếp đến file_get_contents(), nhưng kể từ khi bạn có thể có được một mảng của các dòng trong tập tin, bạn có thể tham gia cùng họ bằng dòng mới, như thế này:

sample = '\n'.join(open(test, 'r').readlines()) 

EDIT : không sao, có một cách dễ dàng hơn nhiều: sample = file(test).read()

Chuỗi thay thế gần như hoàn toàn giống như str_replace():

sample = sample.replace(search, replace) 

Và xuất ra cũng đơn giản như một tuyên bố print:

print defang_word(sample) 

Như bạn có thể thấy, hai phiên bản nhìn gần như giống hệt nhau.

+0

tệp ('foo.txt'). Đọc() – Justus

+0

Cuộc gọi tốt — được chỉnh sửa. – hbw

+0

@Justus, sẽ không 'file (name) .read() 'mô tả tệp rò rỉ, vì bạn không bao giờ gọi gần? –