एक स्ट्रिंग को रिक्त स्थान से विभाजित करें - उद्धृत पदार्थों को संरक्षित करना - पायथन में


269

मेरे पास एक स्ट्रिंग है जो इस प्रकार है:

this is "a test"

मैं पायथन में कुछ लिखने की कोशिश कर रहा हूं, उद्धरणों के भीतर रिक्त स्थान की अनदेखी करते हुए इसे अंतरिक्ष से विभाजित करने के लिए। परिणाम मैं देख रहा हूँ:

['this','is','a test']

पुनश्च। मुझे पता है कि आप पूछने जा रहे हैं "क्या होगा अगर उद्धरण के भीतर उद्धरण हैं, ठीक है, मेरे आवेदन में, ऐसा कभी नहीं होगा।


1
यह सवाल पूछने के लिए धन्यवाद। यह वही है जो मुझे pypar बिल्ड मॉड्यूल को ठीक करने के लिए आवश्यक था।
मार्टलार्क

जवाबों:


392

आप चाहते हैं split, अंतर्निहित shlexमॉड्यूल से।

>>> import shlex
>>> shlex.split('this is "a test"')
['this', 'is', 'a test']

यह वही करना चाहिए जो आप चाहते हैं।


13
कोटेशन को संरक्षित करने के लिए "पॉज़िक्स = गलत" का उपयोग करें। shlex.split('this is "a test"', posix=False)रिटर्न['this', 'is', '"a test"']
बून

@MatthewG। पायथन 2.7.3 में "फिक्स" का अर्थ है कि shlex.split()एक UnicodeEncodeErrorअपवाद को ट्रिगर करने के लिए एक यूनिकोड स्ट्रिंग पास करना ।
3

57

shlexविशेष रूप से मॉड्यूल पर एक नज़र डालें shlex.split

>>> import shlex
>>> shlex.split('This is "a test"')
['This', 'is', 'a test']

40

मुझे यहां रेगेक्स दृष्टिकोण दिखाई देता है जो जटिल और / या गलत दिखता है। यह मुझे आश्चर्यचकित करता है, क्योंकि रेगेक्स सिंटैक्स आसानी से "व्हाट्सएप या चीज से घिरा हुआ-उद्धरण" का वर्णन कर सकता है, और अधिकांश रेगेक्स इंजन (पायथन सहित) एक रेक्स पर विभाजित हो सकते हैं। तो अगर आप regexes का उपयोग करने जा रहे हैं, तो बस वही क्यों न कहें जो आपका मतलब है? "

test = 'this is "a test"'  # or "this is 'a test'"
# pieces = [p for p in re.split("( |[\\\"'].*[\\\"'])", test) if p.strip()]
# From comments, use this:
pieces = [p for p in re.split("( |\\\".*?\\\"|'.*?')", test) if p.strip()]

स्पष्टीकरण:

[\\\"'] = double-quote or single-quote
.* = anything
( |X) = space or X
.strip() = remove space and empty-string separators

श्लेक्स शायद अधिक सुविधाएँ प्रदान करता है, यद्यपि।


1
मैं बहुत कुछ ऐसा ही सोच रहा था, लेकिन इसके बजाय सुझाव देंगे कि [t.strip ('' '') t में re.findall (r '[^ \ s "] + |" | "[^"] * "', 'यह है" a test "')]
डेरियस बेकन

2
+1 मैं इसका उपयोग कर रहा हूं क्योंकि यह श्लेक्स की तुलना में बहुत तेज था।
११:४४ बजे हनलेप

3
ट्रिपल बैकस्लैश क्यों? एक साधारण बैकलैश नहीं होगा?
डोपेलगैंगर

1
वास्तव में, एक बात जो मुझे पसंद नहीं है, वह यह है कि उद्धरण से पहले / बाद में कुछ भी ठीक से विभाजित नहीं किया गया है। अगर मेरे पास इस तरह का एक स्ट्रिंग है 'PARAMS val1 = "थिंग" val2 = "थिंग 2"। मैं स्ट्रिंग को तीन टुकड़ों में विभाजित करने की उम्मीद करता हूं, लेकिन यह 5 में विभाजित हो जाता है। मुझे रेगेक्स किए हुए कुछ समय हो गया है, इसलिए मुझे आपके समाधान का उपयोग करके इसे हल करने की कोशिश करने का मन नहीं है।
लेटनाइटशेड

1
आपको नियमित अभिव्यक्ति का उपयोग करते समय कच्चे तारों का उपयोग करना चाहिए।
asmeurer

29

आपके उपयोग के मामले के आधार पर, आप csvमॉड्यूल की जांच करना भी चाहेंगे :

import csv
lines = ['this is "a string"', 'and more "stuff"']
for row in csv.reader(lines, delimiter=" "):
    print(row)

आउटपुट:

['this', 'is', 'a string']
['and', 'more', 'stuff']

2
उपयोगी, जब श्लेक्स कुछ आवश्यक पात्रों को स्ट्रिप्स करता है
स्क्रैप करें

1
CSV एक पंक्ति में दो दोहरे उद्धरणों का उपयोग करता है (जैसा कि साइड-बाय-साइड में "") , एक दोहरे उद्धरण का प्रतिनिधित्व करने के लिए ", इसलिए दो दोहरे उद्धरणों को एक एकल उद्धरण में बदल देगा 'this is "a string""'और 'this is "a string"""'दोनों मानचित्र['this', 'is', 'a string"']
बोरिस

15

मैं स्क्वीड लॉग की 70,000,000 लाइनों को संसाधित करने के लिए shlex.split का उपयोग करता हूं, यह इतना धीमा है। इसलिए मैंने फिर से स्विच किया।

कृपया इसे आज़माएं, अगर आपको श्लेक्स के साथ प्रदर्शन की समस्या है।

import re

def line_split(line):
    return re.findall(r'[^"\s]\S*|".+?"', line)

8

चूँकि यह प्रश्न regex के साथ टैग किया गया है, इसलिए मैंने regex दृष्टिकोण आज़माने का निर्णय लिया। मैं पहले उद्धरण भागों के सभी हिस्सों को \ x00 के साथ प्रतिस्थापित करता हूं, फिर रिक्त स्थान से विभाजित करता हूं, फिर प्रत्येक भाग में रिक्त स्थान के लिए \ x00 को प्रतिस्थापित करता हूं।

दोनों संस्करण एक ही काम करते हैं, लेकिन फाड़नेवाला थोड़ा अधिक पठनीय है तो अलग है।

import re

s = 'this is "a test" some text "another test"'

def splitter(s):
    def replacer(m):
        return m.group(0).replace(" ", "\x00")
    parts = re.sub('".+?"', replacer, s).split()
    parts = [p.replace("\x00", " ") for p in parts]
    return parts

def splitter2(s):
    return [p.replace("\x00", " ") for p in re.sub('".+?"', lambda m: m.group(0).replace(" ", "\x00"), s).split()]

print splitter2(s)

आपको इसके बजाय re.Scanner का उपयोग करना चाहिए था। यह अधिक विश्वसनीय है (और मैं वास्तव में पुनः उपयोग कर रहा हूँ।
डेविन जीनपिएरे

+1 एचएम, यह एक बहुत ही अच्छा विचार है, समस्या को कई चरणों में तोड़ना है ताकि उत्तर बहुत जटिल न हो। श्लेक्स ने ठीक वैसा ही नहीं किया जैसा मुझे चाहिए था, यहाँ तक कि इसे ट्विक करने की भी कोशिश कर रहा था। और सिंगल पास रेगेक्स समाधान वास्तव में अजीब और जटिल हो रहे थे।
लेटनाइटशेड

6

ऐसा लगता है कि प्रदर्शन के कारणों reमें तेजी है। यहाँ मेरा समाधान कम से कम लालची ऑपरेटर का उपयोग करके है जो बाहरी उद्धरणों को संरक्षित करता है:

re.findall("(?:\".*?\"|\S)+", s)

परिणाम:

['this', 'is', '"a test"']

यह aaa"bla blub"bbbएक साथ निर्माण छोड़ देता है क्योंकि ये टोकन रिक्त स्थान से अलग नहीं होते हैं। यदि स्ट्रिंग में बच गए अक्षर हैं, तो आप इस तरह मेल कर सकते हैं:

>>> a = "She said \"He said, \\\"My name is Mark.\\\"\""
>>> a
'She said "He said, \\"My name is Mark.\\""'
>>> for i in re.findall("(?:\".*?[^\\\\]\"|\S)+", a): print(i)
...
She
said
"He said, \"My name is Mark.\""

कृपया ध्यान दें कि यह पैटर्न ""के \Sहिस्से के माध्यम से रिक्त स्ट्रिंग से मेल खाता है ।


1
इस समाधान का एक अन्य महत्वपूर्ण लाभ इसकी बहुमुखी प्रतिभा के संबंध में परिसीमन चरित्र (जैसे के ,माध्यम से '(?:".*?"|[^,])+') है। वही उद्धृत (संलग्न) वर्ण (एस) पर लागू होता है।
a_guest

4

स्वीकृत shlexदृष्टिकोण के साथ मुख्य समस्या यह है कि उद्धृत उद्धरणों के बाहर भागने वाले पात्रों को अनदेखा नहीं करता है, और कुछ कोने के मामलों में थोड़ा अप्रत्याशित परिणाम देता है।

मेरे पास निम्नलिखित उपयोग का मामला है, जहां मुझे एक विभाजन फ़ंक्शन की आवश्यकता होती है जो इनपुट स्ट्रिंग्स को विभाजित करता है जैसे कि या तो एकल-उद्धृत या दोहरे-उद्धरण वाले सब्सट्रेटिंग संरक्षित हैं, ऐसे विकल्प के भीतर उद्धरण से बचने की क्षमता है। एक निर्विवाद स्ट्रिंग के भीतर उद्धरण किसी अन्य चरित्र से अलग तरह से व्यवहार नहीं किया जाना चाहिए। अपेक्षित उत्पादन के साथ कुछ उदाहरण परीक्षण मामले:

इनपुट स्ट्रिंग | अपेक्षित उत्पादन
===============================================
 'abc def' | ['abc', 'def']
 "abc \\ s def" | ['abc', '\\ s', 'def']
 '' '' एबीसी दे '' घी '' | ['abc def', 'ghi']
 "" एबीसी डीई 'जी "| ['abc def', 'ghi']
 "" एबीसी \\ "डिफ" गि "। ['एबीसी" डीईएफ़,' गि '']
 "" abc \\ 'def' ghi "| ["abc 'def",' ghi ']
 "" abc \\ s def 'ghi "| ['abc \\ s def', 'ghi']
 "" abc \\ s def "ghi" | ['abc \\ s def', 'ghi']
 '' '' परीक्षण '' | ['', 'परीक्षा']
 "" 'परीक्षण "| ['', 'परीक्षा']
 "abc'def" | [ "Abc'def"]
 "abc'def '" | [ "Abc'def '"]
 "abc'def 'ghi" | ["abc'def" ", 'घी']
 "abc'def'ghi" | [ "Abc'def'ghi"]
 "एबीसी" डीईएफ़।] ['एबीसी' डीफ़ ']
 "एबीसी" डीफ़ "" | [ 'एबीसी "def"']
 g abc ”def“ घी ’| ['abc "def",' ghi ']
 g abc ”def“ घी ’| [ 'एबीसी "def" GHI']
 "r'AA 'r'। * _ xyz $ '" | ["r'AA '", "r'। * _ xyz $ '"]

मैंने निम्नलिखित फ़ंक्शन के साथ एक स्ट्रिंग को विभाजित करने के लिए समाप्त किया, ताकि सभी इनपुट स्ट्रिंग के लिए अपेक्षित आउटपुट परिणाम मिलें:

import re

def quoted_split(s):
    def strip_quotes(s):
        if s and (s[0] == '"' or s[0] == "'") and s[0] == s[-1]:
            return s[1:-1]
        return s
    return [strip_quotes(p).replace('\\"', '"').replace("\\'", "'") \
            for p in re.findall(r'"(?:\\.|[^"])*"|\'(?:\\.|[^\'])*\'|[^\s]+', s)]

निम्नलिखित परीक्षण एप्लिकेशन अन्य दृष्टिकोणों ( shlexऔर csvअभी के लिए) और कस्टम विभाजन कार्यान्वयन के परिणामों की जांच करता है :

#!/bin/python2.7

import csv
import re
import shlex

from timeit import timeit

def test_case(fn, s, expected):
    try:
        if fn(s) == expected:
            print '[ OK ] %s -> %s' % (s, fn(s))
        else:
            print '[FAIL] %s -> %s' % (s, fn(s))
    except Exception as e:
        print '[FAIL] %s -> exception: %s' % (s, e)

def test_case_no_output(fn, s, expected):
    try:
        fn(s)
    except:
        pass

def test_split(fn, test_case_fn=test_case):
    test_case_fn(fn, 'abc def', ['abc', 'def'])
    test_case_fn(fn, "abc \\s def", ['abc', '\\s', 'def'])
    test_case_fn(fn, '"abc def" ghi', ['abc def', 'ghi'])
    test_case_fn(fn, "'abc def' ghi", ['abc def', 'ghi'])
    test_case_fn(fn, '"abc \\" def" ghi', ['abc " def', 'ghi'])
    test_case_fn(fn, "'abc \\' def' ghi", ["abc ' def", 'ghi'])
    test_case_fn(fn, "'abc \\s def' ghi", ['abc \\s def', 'ghi'])
    test_case_fn(fn, '"abc \\s def" ghi', ['abc \\s def', 'ghi'])
    test_case_fn(fn, '"" test', ['', 'test'])
    test_case_fn(fn, "'' test", ['', 'test'])
    test_case_fn(fn, "abc'def", ["abc'def"])
    test_case_fn(fn, "abc'def'", ["abc'def'"])
    test_case_fn(fn, "abc'def' ghi", ["abc'def'", 'ghi'])
    test_case_fn(fn, "abc'def'ghi", ["abc'def'ghi"])
    test_case_fn(fn, 'abc"def', ['abc"def'])
    test_case_fn(fn, 'abc"def"', ['abc"def"'])
    test_case_fn(fn, 'abc"def" ghi', ['abc"def"', 'ghi'])
    test_case_fn(fn, 'abc"def"ghi', ['abc"def"ghi'])
    test_case_fn(fn, "r'AA' r'.*_xyz$'", ["r'AA'", "r'.*_xyz$'"])

def csv_split(s):
    return list(csv.reader([s], delimiter=' '))[0]

def re_split(s):
    def strip_quotes(s):
        if s and (s[0] == '"' or s[0] == "'") and s[0] == s[-1]:
            return s[1:-1]
        return s
    return [strip_quotes(p).replace('\\"', '"').replace("\\'", "'") for p in re.findall(r'"(?:\\.|[^"])*"|\'(?:\\.|[^\'])*\'|[^\s]+', s)]

if __name__ == '__main__':
    print 'shlex\n'
    test_split(shlex.split)
    print

    print 'csv\n'
    test_split(csv_split)
    print

    print 're\n'
    test_split(re_split)
    print

    iterations = 100
    setup = 'from __main__ import test_split, test_case_no_output, csv_split, re_split\nimport shlex, re'
    def benchmark(method, code):
        print '%s: %.3fms per iteration' % (method, (1000 * timeit(code, setup=setup, number=iterations) / iterations))
    benchmark('shlex', 'test_split(shlex.split, test_case_no_output)')
    benchmark('csv', 'test_split(csv_split, test_case_no_output)')
    benchmark('re', 'test_split(re_split, test_case_no_output)')

आउटपुट:

shlex

[ठीक है] abc def -> ['abc', 'def']
[विफल] abc \ s def -> ['abc', 's', 'def']
[ठीक है] "abc def" ghi -> ['abc def', 'ghi']
[ठीक है] 'एबीसी डीईए' गि -> ['एबीसी डीएफ ’,' जीआईएच]
[ठीक है] "abc \" को "ghi -> [" abc "को परिभाषित करें, 'ghi']
[विफल] 'abc \' def 'ghi -> अपवाद: कोई समापन उद्धरण नहीं
[ठीक है] 'abc \ s def' ghi -> ['abc \\ s def', 'ghi']
[ठीक है] "abc \ s def" ghi -> ['abc \\ s def', 'ghi']
[ठीक] "" परीक्षण -> ['', 'परीक्षण']
[ठीक है] '' परीक्षण -> ['', 'परीक्षण']
[विफल] abc'def -> अपवाद: कोई समापन उद्धरण नहीं
[विफल] abc'def '-> [' abcdef ']
[FAIL] abc'def 'ghi -> [' abcdef ',' ghi ']
[विफल] abc'def'ghi -> ['abcdefghi']
[विफल] abc "def -> अपवाद: कोई समापन उद्धरण नहीं
[FAIL] abc "def" -> ['abcdef']
[FAIL] abc "def" ghi -> ['abcdef', 'ghi']
[FAIL] abc "def" ghi -> ['abcdefghi']
[FAIL] r'AA 'r'। * _ Xyz $ '-> [' rAA ',' r। * _ Xyz $ ']

सीएसवी

[ठीक है] abc def -> ['abc', 'def']
[ठीक] abc \ s def -> ['abc', '\\ s', 'def']
[ठीक है] "abc def" ghi -> ['abc def', 'ghi']
[FAIL] 'abc def' ghi -> ["abc", "def '",' ghi ']
[FAIL] "abc \" def "ghi -> ['abc \\', 'def"','hi ']
[FAIL] 'abc \' def 'ghi -> ["" abc "," \\' "," def '",' ghi ']
[विफल] 'abc \ s def' ghi -> ["abc", '\\ s', "def '",' ghi ']
[ठीक है] "abc \ s def" ghi -> ['abc \\ s def', 'ghi']
[ठीक] "" परीक्षण -> ['', 'परीक्षण']
[विफल] '' परीक्षण -> ["" "," परीक्षण ']
[ठीक है] abc'def -> ["abc'def"]
[ठीक है] abc'def '-> ["abc'def'"]
[ठीक है] abc'def 'ghi -> ["abc'def" ",' ghi ']
[ठीक है] abc'def'ghi -> ["abc'def'ghi"
[ठीक है] abc "def -> ['abc" def']
[ठीक] abc "def" -> ['abc "def"']
[ओके] एबीसी "डीईई" गि -> ['एबीसी "डीफ़" "," जीआईएच]]
[ठीक है] एबीसी "डीईई" गि -> [एबीसी "डीईएटी" जीआईएच]]
[ठीक है] r'AA 'r'। * _ xyz $ '-> ["r'AA'", "r '। * _ xyz $'"]

फिर से

[ठीक है] abc def -> ['abc', 'def']
[ठीक] abc \ s def -> ['abc', '\\ s', 'def']
[ठीक है] "abc def" ghi -> ['abc def', 'ghi']
[ठीक है] 'एबीसी डीईए' गि -> ['एबीसी डीएफ ’,' जीआईएच]
[ठीक है] "abc \" को "ghi -> [" abc "को परिभाषित करें, 'ghi']
[ठीक है] 'abc \' def 'ghi -> ["abc' def", 'ghi']
[ठीक है] 'abc \ s def' ghi -> ['abc \\ s def', 'ghi']
[ठीक है] "abc \ s def" ghi -> ['abc \\ s def', 'ghi']
[ठीक] "" परीक्षण -> ['', 'परीक्षण']
[ठीक है] '' परीक्षण -> ['', 'परीक्षण']
[ठीक है] abc'def -> ["abc'def"]
[ठीक है] abc'def '-> ["abc'def'"]
[ठीक है] abc'def 'ghi -> ["abc'def" ",' ghi ']
[ठीक है] abc'def'ghi -> ["abc'def'ghi"
[ठीक है] abc "def -> ['abc" def']
[ठीक] abc "def" -> ['abc "def"']
[ओके] एबीसी "डीईई" गि -> ['एबीसी "डीफ़" "," जीआईएच]]
[ठीक है] एबीसी "डीईई" गि -> [एबीसी "डीईएटी" जीआईएच]]
[ठीक है] r'AA 'r'। * _ xyz $ '-> ["r'AA'", "r '। * _ xyz $'"]

श्लेक्स: 0.281ms प्रति पुनरावृत्ति
सीएसवी: बग्स प्रति पुनरावृत्ति
पुन: 0.049ms प्रति पुनरावृत्ति

इसलिए प्रदर्शन की तुलना में बहुत बेहतर है shlex, और नियमित अभिव्यक्ति को आगे बढ़ाकर सुधार किया जा सकता है, इस मामले में यह csvदृष्टिकोण को बेहतर बना देगा ।


निश्चित नहीं कि आप किस बारे में बात कर रहे हैं: `` `>>> shlex.split ('यह एक परीक्षण है' ') [' यह ',' है ',' एक परीक्षण '] >>> shlex.split (') यह \\ "a test \\" ") ['this', 'is', '" a', >> test "'] >>> shlex.split (' यह" a \\ "test \\" है " ")" '' यह ',' है ',' ए 'परीक्षण' '] `` `
morsik

@ मॉर्शिक, आपकी बात क्या है? हो सकता है कि आपका उपयोग मामला मेरा से मेल नहीं खाता हो? जब आप परीक्षण मामलों को देखते हैं तो आप उन सभी मामलों को देखेंगे जहां shlexमेरे उपयोग के मामलों के लिए अपेक्षित व्यवहार नहीं होता है।
टन वैन डेन हेउवेल

3

उद्धरणों को संरक्षित करने के लिए इस फ़ंक्शन का उपयोग करें:

def getArgs(s):
    args = []
    cur = ''
    inQuotes = 0
    for char in s.strip():
        if char == ' ' and not inQuotes:
            args.append(cur)
            cur = ''
        elif char == '"' and not inQuotes:
            inQuotes = 1
            cur += char
        elif char == '"' and inQuotes:
            inQuotes = 0
            cur += char
        else:
            cur += char
    args.append(cur)
    return args

जब बड़े स्ट्रिंग के साथ तुलना की जाती है, तो आपका कार्य बहुत धीमा होता है
Faran2007

3

विभिन्न उत्तरों की गति परीक्षण:

import re
import shlex
import csv

line = 'this is "a test"'

%timeit [p for p in re.split("( |\\\".*?\\\"|'.*?')", line) if p.strip()]
100000 loops, best of 3: 5.17 µs per loop

%timeit re.findall(r'[^"\s]\S*|".+?"', line)
100000 loops, best of 3: 2.88 µs per loop

%timeit list(csv.reader([line], delimiter=" "))
The slowest run took 9.62 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.4 µs per loop

%timeit shlex.split(line)
10000 loops, best of 3: 50.2 µs per loop

1

हम्म, "उत्तर" बटन को खोजने के लिए प्रतीत नहीं हो सकता ... वैसे भी, यह जवाब केट द्वारा दृष्टिकोण पर आधारित है, लेकिन सही ढंग से बच गए उद्धरणों वाले सब्सट्रिंग के साथ तारों को विभाजित करता है और सब्सट्रिंग के शुरू और अंत उद्धरण को भी हटाता है:

  [i.strip('"').strip("'") for i in re.split(r'(\s+|(?<!\\)".*?(?<!\\)"|(?<!\\)\'.*?(?<!\\)\')', string) if i.strip()]

यह स्ट्रिंग्स पर काम करता है जैसे 'This is " a \\\"test\\\"\\\'s substring"'(पागल मार्कअप दुर्भाग्य से पलायन को दूर करने के लिए आवश्यक है)।

यदि दी गई सूची में तार के परिणामस्वरूप भाग नहीं चाहते हैं, तो आप फ़ंक्शन के इस थोड़े परिवर्तित संस्करण का उपयोग कर सकते हैं:

[i.strip('"').strip("'").decode('string_escape') for i in re.split(r'(\s+|(?<!\\)".*?(?<!\\)"|(?<!\\)\'.*?(?<!\\)\')', string) if i.strip()]

1

कुछ पायथन 2 संस्करणों में यूनिकोड मुद्दों के आसपास जाने के लिए, मैं सुझाव देता हूं:

from shlex import split as _split
split = lambda a: [b.decode('utf-8') for b in _split(a.encode('utf-8'))]

अजगर 2.7.5 के लिए यह होना चाहिए: split = lambda a: [b.decode('utf-8') for b in _split(a)]अन्यथा आपको मिलता है:UnicodeDecodeError: 'ascii' codec can't decode byte ... in position ...: ordinal not in range(128)
पीटर वारो


0

मैं सुझाव देता हूँ:

परीक्षण स्ट्रिंग:

s = 'abc "ad" \'fg\' "kk\'rdt\'" zzz"34"zzz "" \'\''

"" और '' को पकड़ने के लिए:

import re
re.findall(r'"[^"]*"|\'[^\']*\'|[^"\'\s]+',s)

परिणाम:

['abc', '"ad"', "'fg'", '"kk\'rdt\'"', 'zzz', '"34"', 'zzz', '""', "''"]

खाली "" और '' को अनदेखा करने के लिए:

import re
re.findall(r'"[^"]+"|\'[^\']+\'|[^"\'\s]+',s)

परिणाम:

['abc', '"ad"', "'fg'", '"kk\'rdt\'"', 'zzz', '"34"', 'zzz']

के रूप में re.findall("(?:\".*?\"|'.*?'|[^\s'\"]+)", s)भी लिखा जा सकता है ।
hochl

-3

यदि आप एक सरल से उप तार के बारे में परवाह नहीं है

>>> 'a short sized string with spaces '.split()

प्रदर्शन:

>>> s = " ('a short sized string with spaces '*100).split() "
>>> t = timeit.Timer(stmt=s)
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
171.39 usec/pass

या स्ट्रिंग मॉड्यूल

>>> from string import split as stringsplit; 
>>> stringsplit('a short sized string with spaces '*100)

प्रदर्शन: स्ट्रिंग मॉड्यूल स्ट्रिंग विधियों की तुलना में बेहतर प्रदर्शन करता है

>>> s = "stringsplit('a short sized string with spaces '*100)"
>>> t = timeit.Timer(s, "from string import split as stringsplit")
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
154.88 usec/pass

या आप आरई इंजन का उपयोग कर सकते हैं

>>> from re import split as resplit
>>> regex = '\s+'
>>> medstring = 'a short sized string with spaces '*100
>>> resplit(regex, medstring)

प्रदर्शन

>>> s = "resplit(regex, medstring)"
>>> t = timeit.Timer(s, "from re import split as resplit; regex='\s+'; medstring='a short sized string with spaces '*100")
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
540.21 usec/pass

बहुत लंबे तार के लिए आपको पूरे स्ट्रिंग को मेमोरी में लोड नहीं करना चाहिए और इसके बजाय लाइनों को विभाजित करना या पुनरावृत्त लूप का उपयोग करना चाहिए


11
आपको लगता है कि प्रश्न के पूरे बिंदु से चूक गए हैं। स्ट्रिंग में उद्धृत खंड हैं जिन्हें विभाजित करने की आवश्यकता नहीं है।
rjmunro

-3

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

  def adamsplit(s):
    result = []
    inquotes = False
    for substring in s.split('"'):
      if not inquotes:
        result.extend(substring.split())
      else:
        result.append(substring)
      inquotes = not inquotes
    return result

कुछ परीक्षण तार:

'This is "a test"' -> ['This', 'is', 'a test']
'"This is \'a test\'"' -> ["This is 'a test'"]

कृपया एक स्ट्रिंग की रीप की आपूर्ति करें जो आपको लगता है कि विफल हो जाएगी।
pjz

सोचो ? adamsplit("This is 'a test'")['This', 'is', "'a", "test'"]
मैथ्यू Schinckel 4

ओपी केवल "उद्धरण के भीतर" कहता है और केवल दोहरे उद्धरण चिह्नों के साथ एक उदाहरण है।
13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.