2008-12-14 19 views
38

मैं स्ट्रिंग द्वारा उत्पादित सूची में विराम चिह्न जोड़कर शब्दों और विराम चिह्न में एक स्ट्रिंग को विभाजित करने की कोशिश कर रहा हूं।शब्दों और विराम चिह्न में एक स्ट्रिंग को विभाजित करना

उदाहरण के लिए:

>>> c = "help, me" 
>>> print c.split() 
['help,', 'me'] 

क्या मैं सच की तरह लग रहे करने के लिए सूची चाहते हैं:

['help', ',', 'me'] 

तो, मैं शब्दों से विराम चिह्न विभाजन के साथ खाली स्थान के पर स्ट्रिंग विभाजन चाहते हैं।

मैं पहली स्ट्रिंग पार्स और विभाजन तो चलाने के लिए कोशिश की है:

>>> for character in c: 
...  if character in ".,;!?": 
...    outputCharacter = " %s" % character 
...  else: 
...    outputCharacter = character 
...  separatedPunctuation += outputCharacter 
>>> print separatedPunctuation 
help , me 
>>> print separatedPunctuation.split() 
['help', ',', 'me'] 

यह परिणाम मैं चाहता हूँ पैदा करता है, लेकिन दर्दनाक बड़ी फ़ाइलों पर धीमी है।

क्या यह और अधिक कुशलतापूर्वक करने का कोई तरीका है?

+0

इस उदाहरण (नहीं सामान्य मामले) 'c.replace के लिए ('', '') विभाजन (',')' –

उत्तर

57

यह कम या ज्यादा जिस तरह से यह करना है।

चेतावनियां:

  • अंडरस्कोर (_) एक भीतरी शब्द चरित्र माना जाता है। यदि आप इसे नहीं चाहते हैं तो \ w बदलें।
  • यह स्ट्रिंग में (एकल) उद्धरण के साथ काम नहीं करेगा।
  • कोई भी अतिरिक्त विराम चिह्न जो आप नियमित अभिव्यक्ति के दाहिने हिस्से में उपयोग करना चाहते हैं।
  • कुछ भी स्पष्ट रूप से उल्लेख नहीं किया गया है चुपचाप गिरा दिया गया है।
+0

धन्यवाद, पूरी तरह से काम करता है। –

+2

यदि आप किसी भी विराम चिह्न में विभाजित करना चाहते हैं, जिसमें '' ', 're.findall (r" [\ w] + | [^ \ s \ w] "," हैलो, मैं एक स्ट्रिंग हूं! " । परिणाम '[' हैलो ',', ',' मैं ',' '', 'एम', 'ए', 'स्ट्रिंग', '!'] 'ध्यान दें कि शब्द मिलान में अंक शामिल हैं। –

+0

क्षमा करें! क्या आप समझा सकते हैं कि यह वास्तव में कैसे काम कर रहा है? – Curious

-1

क्या आपने रेगेक्स का उपयोग करने का प्रयास किया है?

http://docs.python.org/library/re.html#re-syntax


वैसे। आपको दूसरी बार "," क्यों चाहिए? आपको पता चल जाएगा कि उसके बाद प्रत्येक पाठ लिखा है यानी

[0]

","

[1]

","

तो तुम जोड़ें "करना चाहते हैं , "जब आप सरणी का उपयोग करते हैं तो आप इसे प्रत्येक पुनरावृत्ति के बाद कर सकते हैं ..

4

पर्ल-शैली नियमित अभिव्यक्ति वाक्यविन्यास में, \b शब्द सीमा से मेल खाता है। यह regex- आधारित विभाजन करने के लिए काम में आना चाहिए।

संपादित करें: मुझे आशा है कि "खाली मिलान" पाइथन के पुनः मॉड्यूल के विभाजन समारोह में काम नहीं करते हैं। मैं इसे यहां "फीचर" से फंसने वाले किसी और के लिए जानकारी के रूप में छोड़ दूंगा।

+0

केवल इसलिए नहीं है क्योंकि re.split r '\ b' के साथ काम नहीं करेगा ... – hop

+0

क्या है? क्या यह re.split में एक बग है? पर्ल में, 'विभाजित/\ b \ s */'बिना किसी समस्या के काम करता है। – Svante

+0

यह दस्तावेज है कि re.split() खाली मैचों पर विभाजित नहीं होगा ... इसलिए, नहीं, वास्तव में/वास्तव में/एक बग नहीं। – hop

0

मुझे लगता है कि आप NLTK में कल्पना कर सकते हैं कि सभी मदद मिल सकती है, खासकर जब से आप पाइथन का उपयोग कर रहे हैं। ट्यूटोरियल में इस मुद्दे की एक अच्छी व्यापक चर्चा है।

1

यहां आपके कार्यान्वयन के लिए एक मामूली अपडेट है। यदि आप कुछ और अधिक विस्तृत करने की कोशिश कर रहे हैं तो मैं एनएलटीके की तलाश करने का सुझाव देता हूं कि ले डोरफ़ियर ने सुझाव दिया था।

यह थोड़ी तेज़ हो सकता है क्योंकि '.join() का उपयोग + = के स्थान पर किया जाता है, जो known to be faster है।

import string 

d = "Hello, I'm a string!" 

result = [] 
word = '' 

for char in d: 
    if char not in string.whitespace: 
     if char not in string.ascii_letters + "'": 
      if word: 
        result.append(word) 
      result.append(char) 
      word = '' 
     else: 
      word = ''.join([word,char]) 

    else: 
     if word: 
      result.append(word) 
      word = '' 
print result 
['Hello', ',', "I'm", 'a', 'string', '!'] 
+0

मैंने इसे प्रोफाइल नहीं किया है, लेकिन मुझे लगता है कि मुख्य समस्या शब्द के चार-दर-चार संगतता के साथ है। मैं इसके बजाय एक सूचकांक और स्लाइस का उपयोग करेंगे। – hop

+0

चाल के साथ मैं आपके समाधान के निष्पादन समय से 50% दाढ़ी दे सकता हूं। re.findall() के साथ मेरा समाधान अभी भी तेज़ है। – hop

+1

लूप समाप्त होने के बाद आपको 'if word: result.append (word)' कॉल करने की आवश्यकता है, अन्यथा अंतिम शब्द परिणाम में नहीं है। –

2

यहां मेरी प्रविष्टि है।

मुझे संदेह है कि यह दक्षता की भावना में कितना अच्छा होगा, या यदि यह सभी मामलों को पकड़ता है ("!!!" एक साथ समूहित नोट करें; यह एक अच्छी बात हो सकती है या नहीं भी हो सकती है)।

>>> import re 
>>> import string 
>>> s = "Helo, my name is Joe! and i live!!! in a button; factory:" 
>>> l = [item for item in map(string.strip, re.split("(\W+)", s)) if len(item) > 0] 
>>> l 
['Helo', ',', 'my', 'name', 'is', 'Joe', '!', 'and', 'i', 'live', '!!!', 'in', 'a', 'button', ';', 'factory', ':'] 
>>> 

एक स्पष्ट अनुकूलन regex पहले से (re.compile का प्रयोग करके) यदि आप एक पंक्ति-दर-पंक्ति के आधार पर ऐसा करने के लिए जा रहे संकलित करने के लिए किया जाएगा।

>>> import re 
>>> re.findall(r"[\w']+|[.,!?;]", "Hello, I'm a string!") 
['Hello', ',', "I'm", 'a', 'string', '!'] 

चाल है, जहां स्ट्रिंग को विभाजित करने के बारे में सोचना नहीं है, लेकिन क्या टोकन में शामिल करने के लिए:

22

यहाँ एक यूनिकोड-अवगत संस्करण है:

re.findall(r"\w+|[^\w\s]", text, re.UNICODE) 

पहले विकल्प पकड़ता शब्द वर्णों के क्रम (के रूप में यूनिकोड द्वारा परिभाषित किया गया है, तो "रिज्यूम" ['r', 'sum'] में बदल नहीं होगा); दूसरा सफेद जगहों को अनदेखा करते हुए, व्यक्तिगत गैर-शब्द वर्णों को पकड़ता है।

ध्यान दें कि, शीर्ष उत्तर के विपरीत, यह सिंगल कोट को अलग विराम चिह्न (जैसे "मैं हूं" ->['I', "'", 'm']) के रूप में मानता है। यह एनएलपी में मानक प्रतीत होता है, इसलिए मैं इसे एक विशेषता मानता हूं।

+0

उपरोक्त क्योंकि '\ w + | [^ \ w \ s]' निर्माण स्वीकार्य उत्तर से अधिक सामान्य है लेकिन पायथन 3 में afaik re.UNICODE आवश्यक नहीं होना चाहिए – rloth

0

मैं एक तरह से सभी शब्दों और \W+ पैटर्न \b का उपयोग कर जो hardcoding की जरूरत नहीं है tokenize करने के साथ आया था:

>>> import re 
>>> sentence = 'Hello, world!' 
>>> tokens = [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', sentence)] 
['Hello', ',', 'world', '!'] 

यहाँ .*?\S.*? कुछ भी मिलान एक पैटर्न है कि एक स्थान नहीं है और $ में जोड़ा जाता है है एक स्ट्रिंग में अंतिम टोकन से मेल करें यदि यह विराम चिह्न है।

नोट निम्नलिखित यद्यपि - इस वसीयत समूह विराम चिह्न है कि एक से अधिक प्रतीक के होते हैं:

>>> print [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', '"Oh no", she said')] 
['Oh', 'no', '",', 'she', 'said'] 
बेशक

, आप पाते हैं और साथ विभाजन इस तरह के समूहों कर सकते हैं:

>>> for token in [t.strip() for t in re.findall(r'\b.*?\S.*?(?:\b|$)', '"You can", she said')]: 
...  print re.findall(r'(?:\w+|\W)', token) 

['You'] 
['can'] 
['"', ','] 
['she'] 
['said'] 
0

इस प्रयास करें :।

string_big = "One of Python's coolest features is the string format operator This operator is unique to strings" 
my_list =[] 
x = len(string_big) 
poistion_ofspace = 0 
while poistion_ofspace < x: 
    for i in range(poistion_ofspace,x): 
     if string_big[i] == ' ': 
      break 
     else: 
      continue 
    print string_big[poistion_ofspace:(i+1)] 
    my_list.append(string_big[poistion_ofspace:(i+1)]) 
    poistion_ofspace = i+1 

print my_list 
संबंधित मुद्दे