अजगर: स्ट्रिंग से \ xa0 निकाल रहा है?


241

मैं वर्तमान में HTML फ़ाइल और कॉल करने के लिए सुंदर सूप का उपयोग कर रहा हूं get_text() , लेकिन ऐसा लगता है कि मैं बहुत सारे \ xa0 यूनिकोड के साथ रिक्त स्थान का प्रतिनिधित्व कर रहा हूं। क्या पायथन 2.7 में उन सभी को निकालने और उन्हें रिक्त स्थान में बदलने का एक कुशल तरीका है? मुझे लगता है कि अधिक सामान्यीकृत प्रश्न होगा, क्या यूनिकोड प्रारूपण को हटाने का एक तरीका है?

मैंने उपयोग करने की कोशिश की: line = line.replace(u'\xa0',' ')जैसा कि एक और धागे द्वारा सुझाया गया है, लेकिन यह \ xa0 को u में बदल दिया है, इसलिए अब मेरे पास इसके बजाय हर जगह "u" है। ):

संपादित करें: समस्या को हल करने के लिए लगता है str.replace(u'\xa0', ' ').encode('utf-8'), लेकिन .encode('utf-8')बिना replace()ऐसा करने के कारण लगता है कि यह भी अजीब चरित्र, उदाहरण के लिए \ xc2 थूकने के लिए। क्या कोई इसे समझा सकता है?


कोशिश की है कि पहले से ही, 'ascii' कोडेक 0xa0 को 0 की स्थिति में बाइट को डिकोड नहीं कर सकता है: क्रम में नहीं (128)
zhuyxn

15
यूनिकोड को गले लगाओ। u''एस के बजाय एस का उपयोग करें ''। :-)
jpaugh

1
str.replace (u '\ xa0', '') का उपयोग करने की कोशिश की, लेकिन \ ua0s के बजाय हर जगह "u" मिला: /
zhuyxn

यदि स्ट्रिंग एक यूनिकोड है, तो आपको u' 'प्रतिस्थापन का उपयोग करना होगा , न कि ' '। क्या मूल स्ट्रिंग एक यूनिकोड है?
पेप

जवाबों:


267

\ xa0 वास्तव में लैटिन 1 (आईएसओ 8859-1) में गैर-ब्रेकिंग स्पेस है, chr (160)। आपको इसे एक स्थान से बदलना चाहिए।

string = string.replace(u'\xa0', u' ')

जब .encode ('utf-8'), यह utf-8 को यूनिकोड को एनकोड करेगा, अर्थात प्रत्येक यूनिकोड को 1 से 4 बाइट्स द्वारा दर्शाया जा सकता है। इस स्थिति के लिए, \ xa0 को 2 बाइट्स \ xc2 \ xa0 द्वारा दर्शाया जाता है।

Http://docs.python.org/howto/unicode.html पर पढ़ें ।

कृपया ध्यान दें: 2012 से यह उत्तर, पायथन पर चला गया है, आपको unicodedata.normalizeअभी उपयोग करने में सक्षम होना चाहिए


11
मैं यूनिकोड और वर्ण एन्कोडिंग के बारे में एक बड़ी राशि नहीं जानता .. लेकिन ऐसा लगता है जैसे unicodedata.normalize str.replace की तुलना में अधिक उपयुक्त होगा
DBR

तुम्हारा तार के लिए व्यावहारिक सलाह है, लेकिन ध्यान दें कि इस स्ट्रिंग के सभी संदर्भों को भी बदलना होगा। उदाहरण के लिए, यदि आपके पास कोई प्रोग्राम है जो फ़ाइलें खोलता है, और फ़ाइलों में से एक के नाम में एक गैर-ब्रेकिंग स्थान है, तो आपको इस प्रतिस्थापन को करने के अलावा उस फ़ाइल का नाम बदलना होगा ।
g33kz0r

1
U + 00a0 एक नॉन-ब्रेकेबल स्पेस यूनिकोड चरित्र है जिसे लैटिनb'\xa0' 1 एन्कोडिंग में बाइट के रूप में एन्कोड किया जा सकता है , b'\xc2\xa0'यूटीएफ -8 एन्कोडिंग में दो बाइट्स के रूप में। इसे  html में दर्शाया जा सकता है ।
jfs

3
जब मैं यह कोशिश करता हूं, मुझे मिलता है UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 397: ordinal not in range(128)
gwg

1 घंटे के लिए अटक गया था और अंत में हल हो गया। बहुत बहुत धन्यवाद।
सदन हसन

217

पायथन की unicodedataलाइब्रेरी में कई उपयोगी चीजें हैं । उनमें से एक .normalize()फ़ंक्शन है।

प्रयत्न:

new_str = unicodedata.normalize("NFKD", unicode_str)

यदि आप के बाद के परिणाम नहीं मिलते हैं, तो उपरोक्त लिंक में सूचीबद्ध किसी भी अन्य विधि के साथ NFKD को बदलना।


9
ये जबरदस्त है। यह स्वीकृत उत्तर होना चाहिए।
होउमैन

2
पूर्णतया सहमत। आसान, स्पष्ट, संक्षिप्त और बिंदु समाधान तक। थम्स अप।
बिली झोन

2
इतना निश्चित नहीं है कि आप normalize('NFKD', '1º\xa0dia')'1 sure दीया' लौटाना चाहते हैं, लेकिन यह '1o
दइया


1
आह, अगर पाठ 'कोरिया' है, तो यह कोशिश मत करो। 전부 전부 글자 전부 전부 전부।
चो

18

अपनी लाइन के अंत में .strip () का उपयोग करने का प्रयास करें line.strip()मेरे लिए अच्छी तरह से काम किया


15

इसे सारांशित करने के लिए, कई तरीकों की कोशिश करने के बाद, मैंने ऐसा किया। पीछा किए गए HTML स्ट्रिंग से \ xa0 वर्णों से बचने / हटाने के दो तरीके निम्नलिखित हैं।

मान लें कि हमारे कच्चे html निम्नलिखित हैं:

raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>'

तो इस HTML स्ट्रिंग को साफ करने का प्रयास करें:

from bs4 import BeautifulSoup
raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>'
text_string = BeautifulSoup(raw_html, "lxml").text
print text_string
#u'Dear Parent,\xa0This is a test message,\xa0kindly ignore it.\xa0Thanks'

उपरोक्त कोड इन पात्रों का उत्पादन \ xa0 स्ट्रिंग में। उन्हें ठीक से हटाने के लिए, हम दो तरीकों का उपयोग कर सकते हैं।

विधि # 1 (अनुशंसित): पहले एक सुंदर है Get_text विधि स्ट्रिप तर्क के साथ सच के रूप में तो हमारा कोड बन जाता है:

clean_text = BeautifulSoup(raw_html, "lxml").get_text(strip=True)
print clean_text
# Dear Parent,This is a test message,kindly ignore it.Thanks

विधि # 2: दूसरा विकल्प अजगर की लाइब्रेरी यूनिकोडेटा का उपयोग करना है

import unicodedata
text_string = BeautifulSoup(raw_html, "lxml").text
clean_text = unicodedata.normalize("NFKD",text_string)
print clean_text
# u'Dear Parent,This is a test message,kindly ignore it.Thanks'

मैंने इस ब्लॉग पर इन विधियों को भी विस्तृत किया है जिन्हें आप संदर्भित करना चाहते हैं।


धन्यवाद, विधि 1 वह है जो मैं सब देख रहा था।
वसीम

12

इसे इस्तेमाल करे:

string.replace('\\xa0', ' ')

5
@RyanMartin: यह चार बाइट्स को प्रतिस्थापित करता है : len(b'\\xa0') == 4लेकिन len(b'\xa0') == 1। अगर संभव हो तो; आपको उन अपस्ट्रीम को ठीक करना चाहिए जो इन पलायन को उत्पन्न करते हैं।
jfs

12

मैं अजगर के साथ एक sqlite3 डेटाबेस से कुछ डेटा खींच इस एक ही समस्या में भाग गया। उपरोक्त उत्तर मेरे काम नहीं आए (मुझे यकीन नहीं है), लेकिन यह किया:line = line.decode('ascii', 'ignore') हालांकि, मेरा लक्ष्य रिक्त स्थान के साथ प्रतिस्थापित करने के बजाय \ xa0s को हटा रहा था।

नेड बैचेल्ड द्वारा मुझे इस सुपर-सहायक यूनिकोड ट्यूटोरियल से मिला


14
अब आप कुछ भी हटा रहे हैं जो कि ASCII वर्ण नहीं है, तो आप शायद अपनी वास्तविक समस्या का सामना कर रहे हैं। का उपयोग करते हुए 'ignore'पारी छड़ी के माध्यम से धकेल कर भले ही आप समझ में नहीं आता कि कैसे क्लच .. काम करता है की तरह है
मार्टिन पीटर्स

@MartijnPieters लिंक किए गए यूनिकोड ट्यूटोरियल अच्छे हैं, लेकिन आप पूरी तरह से सही हैं - str.encode(..., 'ignore')यूनिकोड-हैंडलिंग के बराबर है try: ... except: ...। हालांकि यह त्रुटि संदेश छिपा सकता है, यह शायद ही कभी समस्या हल करता है।
dbr

1
EMAIL या URLS से निपटने जैसे कुछ उद्देश्यों के लिए इसका उपयोग करना सही लगता है.decode('ascii', 'ignore')
andilabs

1
samwize का जवाब आपके लिए काम नहीं आया क्योंकि यह यूनिकोड स्ट्रिंग्स पर काम करता है । line.decode()आपके उत्तर में पता चलता है कि आपका इनपुट एक बाइटस्ट्रिंग है (आपको .decode()यूनिकोड स्ट्रिंग पर कॉल नहीं करना चाहिए (इसे लागू करने के लिए, पायथन 3 में विधि को हटा दिया गया है)। मुझे समझ नहीं आता कि आप कैसे ट्यूटोरियल देख सकते हैं। अपने जवाब में जुड़े हुए और बाइट्स और यूनिकोड (उन्हें मिश्रण नहीं है) के बीच का अंतर याद आती है।
JFS

8

मैं मुद्रण योग्य चरित्र के साथ समस्या के लिए गुगली करते हुए यहां समाप्त होता हूं। मैं MySQL का उपयोग करता हूं UTF-8 general_ciऔर पॉलिश भाषा से निपटता हूं । समस्याग्रस्त तार के लिए मुझे निम्नानुसार भविष्यवाणी करनी होगी:

text=text.replace('\xc2\xa0', ' ')

यह सिर्फ तेजी से वर्कअराउंड है और आपको सही एन्कोडिंग सेटअप के साथ संभावित रूप से कुछ प्रयास करना चाहिए।


1
यह काम करता है अगर textएक बाइटस्ट्रिंग है जो utf-8 का उपयोग करके एन्कोडेड पाठ का प्रतिनिधित्व करता है। यदि आप पाठ के साथ काम कर रहे हैं; इसे पहले यूनिकोड को डिकोड करें ( .decode('utf-8')) और इसे बहुत अंत में केवल एक बाईटस्ट्रिंग में एनकोड करें (यदि एपीआई यूनिकोड का सीधे समर्थन नहीं करता है, तो socket)। पाठ पर सभी मध्यवर्ती संचालन यूनिकोड पर किए जाने चाहिए।
12

8

इस कोड को आज़माएं

import re
re.sub(r'[^\x00-\x7F]+','','paste your string here').decode('utf-8','ignore').strip()

4

UTF-8 में 0xA0 (यूनिकोड) 0xC2A0 है। .encode('utf8')बस आपका यूनिकोड 0xA0 लेगा और UTF-8 के 0xC2A0 से बदल देगा। इसलिए 0xC2s की स्पष्टता ... एन्कोडिंग प्रतिस्थापित नहीं कर रहा है, जैसा कि आपने शायद अब महसूस किया है।


1
0xc2a0अस्पष्ट (बाइट ऑर्डर) है। b'\xc2\xa0'इसके बजाय बाइट्स शाब्दिक का उपयोग करें ।
jfs

3

यह एक अंतरिक्ष वर्ण के बराबर है, इसलिए इसे पट्टी करें

print(string.strip()) # no more xa0

1

सुंदर सूप में, आप get_text()स्ट्रिप पैरामीटर पारित कर सकते हैं , जो पाठ की शुरुआत और अंत से सफेद स्थान को स्ट्रिप्स करता है। यह \xa0स्ट्रिंग के प्रारंभ या अंत में होने पर किसी अन्य श्वेत स्थान को हटा देगा । सुंदर सूप ने एक खाली स्ट्रिंग को बदल दिया \xa0और इससे मेरे लिए समस्या हल हो गई।

mytext = soup.get_text(strip=True)

5
strip=Trueकेवल तभी काम करता है जब &nbsp;पाठ के प्रत्येक बिट की शुरुआत या अंत हो। यदि यह पाठ के अन्य वर्णों को इनबिल्ट करता है तो यह स्थान को नहीं हटाएगा।
JFS

1

सामान्य अभिव्यक्ति के साथ सामान्य संस्करण (यह सभी नियंत्रण वर्ण हटा देगा):

import re
def remove_control_chart(s):
    return re.sub(r'\\x..', '', s)

-1

पायथन इसे एक अंतरिक्ष वर्ण की तरह पहचानता है, इसलिए आप splitइसे बिना आर्गनों के ले सकते हैं और एक सामान्य व्हाट्सएप से जुड़ सकते हैं :

line = ' '.join(line.split())
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.