2012-12-05 15 views
12

Tôi có một ứng dụng Django nhận dữ liệu tweet từ API của Twitter và lưu nó vào cơ sở dữ liệu MySQL. Theo như tôi biết (tôi vẫn đang tìm kiếm những điểm tốt hơn về mã hóa ký tự) Tôi đang sử dụng UTF-8 ở mọi nơi, bao gồm mã hóa và đối chiếu MySQL, hoạt động tốt trừ khi một tweet chứa Biểu tượng cảm xúc ký tự Tôi hiểu sử dụng mã hóa bốn byte. Đang cố gắng để cứu họ tạo ra những lời cảnh báo sau đây từ Django:Làm cách nào để lọc các ký tự Emoji từ đầu vào của tôi để tôi có thể lưu trong MySQL <5.5?

/home/biggleszx/.virtualenvs/myvirtualenv/lib/python2.6/site-packages/django/db/backends/mysql/base.py:86 : Cảnh báo: chuỗi giá trị sai: '\ xF0 \ x9F \ x98 \ xAD tôi ...' cho cột 'text' ở hàng 1 trở self.cursor.execute (query, args)

tôi bằng cách sử dụng MySQL 5.1, do đó, sử dụng utf8mb4 không phải là một tùy chọn trừ khi tôi nâng cấp lên 5.5, mà tôi không muốn chỉ (cũng từ những gì tôi đã đọc, hỗ trợ của Django cho điều này không phải là khá sẵn sàng sản xuất, mặc dù điều này có thể không còn chính xác nữa). Tôi cũng đã thấy folks tư vấn cho việc sử dụng BLOB thay vì TEXT trên các cột bị ảnh hưởng, mà tôi cũng không muốn làm như tôi thấy nó sẽ làm hại hiệu suất.

Câu hỏi của tôi là, giả sử tôi không quá lo lắng về việc bảo toàn 100% nội dung tweet, có cách nào tôi có thể lọc ra tất cả ký tự Emoji và thay thế chúng bằng ký tự không phải đa byte, chẳng hạn như đáng kính WHITE MEDIUM SMALL SQUARE (U+25FD)? Tôi nghĩ đây là cách dễ nhất để lưu dữ liệu đó cho thiết lập hiện tại của tôi, mặc dù nếu tôi thiếu một giải pháp rõ ràng khác, tôi rất muốn nghe nó!

FYI, tôi đang sử dụng kho Python 2.6.5 trên Ubuntu 10.04.4 LTS. sys.maxunicode là 1114111, vì vậy đây là bản dựng UCS-4.

Cảm ơn bạn đã đọc.

+0

UTF8 có thể mã hóa phi Các ký tự BMP – SLaks

+3

@SLaks: Có, nhưng bộ ký tự MySQL 'utf8' không thể lưu trữ chúng vì nó chỉ sử dụng 3 byte. –

Trả lời

21

Vì vậy, hóa ra điều này đã được trả lời một vài lần, tôi đã không hoàn toàn có đúng Google-fu để tìm câu hỏi hiện có.

Nhờ Martijn Pieters, giải pháp đến từ thế giới của biểu thức thông thường, đặc biệt là mã này (dựa trên câu trả lời của mình để liên kết đầu tiên ở trên):

import re 
try: 
    # UCS-4 
    highpoints = re.compile(u'[\U00010000-\U0010ffff]') 
except re.error: 
    # UCS-2 
    highpoints = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]') 
# mytext = u'<some string containing 4-byte chars>' 
mytext = highpoints.sub(u'\u25FD', mytext) 

Nhân vật tôi đang thay thế bằng là WHITE MEDIUM SMALL SQUARE (U+25FD), FYI, nhưng có thể là bất kỳ thứ gì. Đối với những người không quen thuộc với UCS, như tôi, đây là một hệ thống để chuyển đổi Unicode và một bản dựng Python nhất định sẽ bao gồm hỗ trợ cho biến thể UCS-2 hoặc UCS-4, mỗi biến có giới hạn trên khác nhau hỗ trợ nhân vật.

Với việc bổ sung mã này, các chuỗi dường như tồn tại trong MySQL 5.1 tốt.

Hy vọng điều này sẽ giúp bất kỳ ai khác trong cùng một tình huống!

13

Tôi đã thử nghiệm giải pháp của BigglesZX và nó không phải là biểu tượng cho biểu tượng cảm xúc của trái tim (❤) sau khi đọc [bài viết wikipedia của biểu tượng cảm xúc] [1] Tôi đã thấy rằng cụm từ thông dụng không bao gồm tất cả các biểu tượng cảm xúc trong khi cũng bao gồm phạm vi khác của unicode mà không phải là biểu tượng cảm xúc.

Các mã sau đây tạo ra 5 biểu thức thông thường mà bao gồm 5 khối biểu tượng cảm xúc trong tiêu chuẩn:

emoji_symbols_pictograms = re.compile(u'[\U0001f300-\U0001f5fF]') 
emoji_emoticons = re.compile(u'[\U0001f600-\U0001f64F]') 
emoji_transport_maps = re.compile(u'[\U0001f680-\U0001f6FF]') 
emoji_symbols = re.compile(u'[\U00002600-\U000026FF]') 
emoji_dingbats = re.compile(u'[\U00002700-\U000027BF]') 

Những khối có thể được sáp nhập trong ba khối (UCS-4):

emoji_block0 = re.compile(u'[\U00002600-\U000027BF]') 
emoji_block1 = re.compile(u'[\U0001f300-\U0001f64F]') 
emoji_block2 = re.compile(u'[\U0001f680-\U0001f6FF]') 

Tương đương của chúng trong UCS-2 là:

emoji_block0 = re.compile(u'[\u2600-\u27BF]') 
emoji_block1 = compile(u'[\uD83C][\uDF00-\uDFFF]') 
emoji_block1b = compile(u'[\uD83D][\uDC00-\uDE4F]') 
emoji_block2 = re.compile(u'[\uD83D][\uDE80-\uDEFF]') 

Vì vậy, cuối cùng chúng ta có thể định nghĩa một e thông thường xpression với tất cả các trường hợp cùng nhau:

import re 
try: 
    # UCS-4 
    highpoints = re.compile(u'([\U00002600-\U000027BF])|([\U0001f300-\U0001f64F])|([\U0001f680-\U0001f6FF])') 
except re.error: 
    # UCS-2 
    highpoints = re.compile(u'([\u2600-\u27BF])|([\uD83C][\uDF00-\uDFFF])|([\uD83D][\uDC00-\uDE4F])|([\uD83D][\uDE80-\uDEFF])') 
# mytext = u'<some string containing 4-byte chars>' 
mytext = highpoints.sub(u'\u25FD', mytext) 
0

Tôi phát hiện ra có một cách thông thường khác có thể nhận dạng biểu tượng cảm xúc. này regex được cung cấp bởi các nhóm nghiên cứu tại blog của instagram-enginnering

u"(?<!&)#(\w|(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED0\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3]|\uD83E[\uDD10-\uDD18\uDD80-\uDD84\uDDC0]|(?:0\u20E3|1\u20E3|2\u20E3|3\u20E3|4\u20E3|5\u20E3|6\u20E3|7\u20E3|8\u20E3|9\u20E3|#\u20E3|\\*\u20E3|\uD83C(?:\uDDE6\uD83C(?:\uDDEB|\uDDFD|\uDDF1|\uDDF8|\uDDE9|\uDDF4|\uDDEE|\uDDF6|\uDDEC|\uDDF7|\uDDF2|\uDDFC|\uDDE8|\uDDFA|\uDDF9|\uDDFF|\uDDEA)|\uDDE7\uD83C(?:\uDDF8|\uDDED|\uDDE9|\uDDE7|\uDDFE|\uDDEA|\uDDFF|\uDDEF|\uDDF2|\uDDF9|\uDDF4|\uDDE6|\uDDFC|\uDDFB|\uDDF7|\uDDF3|\uDDEC|\uDDEB|\uDDEE|\uDDF6|\uDDF1)|\uDDE8\uD83C(?:\uDDF2|\uDDE6|\uDDFB|\uDDEB|\uDDF1|\uDDF3|\uDDFD|\uDDF5|\uDDE8|\uDDF4|\uDDEC|\uDDE9|\uDDF0|\uDDF7|\uDDEE|\uDDFA|\uDDFC|\uDDFE|\uDDFF|\uDDED)|\uDDE9\uD83C(?:\uDDFF|\uDDF0|\uDDEC|\uDDEF|\uDDF2|\uDDF4|\uDDEA)|\uDDEA\uD83C(?:\uDDE6|\uDDE8|\uDDEC|\uDDF7|\uDDEA|\uDDF9|\uDDFA|\uDDF8|\uDDED)|\uDDEB\uD83C(?:\uDDF0|\uDDF4|\uDDEF|\uDDEE|\uDDF7|\uDDF2)|\uDDEC\uD83C(?:\uDDF6|\uDDEB|\uDDE6|\uDDF2|\uDDEA|\uDDED|\uDDEE|\uDDF7|\uDDF1|\uDDE9|\uDDF5|\uDDFA|\uDDF9|\uDDEC|\uDDF3|\uDDFC|\uDDFE|\uDDF8|\uDDE7)|\uDDED\uD83C(?:\uDDF7|\uDDF9|\uDDF2|\uDDF3|\uDDF0|\uDDFA)|\uDDEE\uD83C(?:\uDDF4|\uDDE8|\uDDF8|\uDDF3|\uDDE9|\uDDF7|\uDDF6|\uDDEA|\uDDF2|\uDDF1|\uDDF9)|\uDDEF\uD83C(?:\uDDF2|\uDDF5|\uDDEA|\uDDF4)|\uDDF0\uD83C(?:\uDDED|\uDDFE|\uDDF2|\uDDFF|\uDDEA|\uDDEE|\uDDFC|\uDDEC|\uDDF5|\uDDF7|\uDDF3)|\uDDF1\uD83C(?:\uDDE6|\uDDFB|\uDDE7|\uDDF8|\uDDF7|\uDDFE|\uDDEE|\uDDF9|\uDDFA|\uDDF0|\uDDE8)|\uDDF2\uD83C(?:\uDDF4|\uDDF0|\uDDEC|\uDDFC|\uDDFE|\uDDFB|\uDDF1|\uDDF9|\uDDED|\uDDF6|\uDDF7|\uDDFA|\uDDFD|\uDDE9|\uDDE8|\uDDF3|\uDDEA|\uDDF8|\uDDE6|\uDDFF|\uDDF2|\uDDF5|\uDDEB)|\uDDF3\uD83C(?:\uDDE6|\uDDF7|\uDDF5|\uDDF1|\uDDE8|\uDDFF|\uDDEE|\uDDEA|\uDDEC|\uDDFA|\uDDEB|\uDDF4)|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C(?:\uDDEB|\uDDF0|\uDDFC|\uDDF8|\uDDE6|\uDDEC|\uDDFE|\uDDEA|\uDDED|\uDDF3|\uDDF1|\uDDF9|\uDDF7|\uDDF2)|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C(?:\uDDEA|\uDDF4|\uDDFA|\uDDFC|\uDDF8)|\uDDF8\uD83C(?:\uDDFB|\uDDF2|\uDDF9|\uDDE6|\uDDF3|\uDDE8|\uDDF1|\uDDEC|\uDDFD|\uDDF0|\uDDEE|\uDDE7|\uDDF4|\uDDF8|\uDDED|\uDDE9|\uDDF7|\uDDEF|\uDDFF|\uDDEA|\uDDFE)|\uDDF9\uD83C(?:\uDDE9|\uDDEB|\uDDFC|\uDDEF|\uDDFF|\uDDED|\uDDF1|\uDDEC|\uDDF0|\uDDF4|\uDDF9|\uDDE6|\uDDF3|\uDDF7|\uDDF2|\uDDE8|\uDDFB)|\uDDFA\uD83C(?:\uDDEC|\uDDE6|\uDDF8|\uDDFE|\uDDF2|\uDDFF)|\uDDFB\uD83C(?:\uDDEC|\uDDE8|\uDDEE|\uDDFA|\uDDE6|\uDDEA|\uDDF3)|\uDDFC\uD83C(?:\uDDF8|\uDDEB)|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C(?:\uDDF9|\uDDEA)|\uDDFF\uD83C(?:\uDDE6|\uDDF2|\uDDFC))))[\ufe00-\ufe0f\u200d]?)+ 

Nguồn: http://instagram-engineering.tumblr.com/post/118304328152/emojineering-part-2-implementing-hashtag-emoji

lưu ý: tôi thêm câu trả lời khác là một điều này không complemetary để câu trả lời trước của tôi ở đây.

0

tôi đang sử dụng chức năng mã hóa json mã hóa đầu vào.

chức năng này được sử dụng cho mã hóa dict (để chuyển đổi nó thành chuỗi) trên json.dumps. (Vì vậy chúng tôi cần phải làm một số chỉnh sửa để đáp ứng - loại bỏ các ' " ')

này giúp tôi tiết kiệm được biểu tượng cảm xúc để mysql, và trình bày nó (tại web):

# encode input 
from json.encoder import py_encode_basestring_ascii 
name = py_encode_basestring_ascii(name)[1:-1] 

# save 
YourModel.name = name 
name.save()