एक स्ट्रिंग के बाएं हिस्से को कैसे निकालना है?


144

मेरे पास कुछ सरल अजगर कोड है जो एक स्ट्रिंग के लिए फ़ाइलों की खोज करता है जैसे path=c:\path, जहां c:\pathभाग भिन्न हो सकता है। वर्तमान कोड है:

def find_path(i_file):
    lines = open(i_file).readlines()
    for line in lines:
        if line.startswith("Path="):
            return # what to do here in order to get line content after "Path=" ?

पाठ प्राप्त करने का एक सरल तरीका क्या है Path=?


ध्यान रखें कि आप "पथ =" से शुरू होने वाली फ़ाइल के भीतर पहली पंक्ति में आ रहे हैं। इस पोस्ट के अन्य उत्तर भी करते हैं। लेकिन अगर फाइल DOS बैच फाइल की तरह कुछ है तो आप वास्तव में इस तरह की फाइल से अंतिम पंक्ति में घटना चाहते हो सकते हैं यदि "बैच" या कमांड फाइल सशर्त नहीं है।
DevPlayer

जवाबों:


23

में शुरू Python 3.9, आप उपयोग कर सकते हैं removeprefix:

'Path=helloworld'.removeprefix('Path=')
# 'helloworld'

5
समय यात्रा बहुत? ; PEP 596 से ; पियथॉन
ssc

मैं अजगर 3.9 के लिए समाधान लिखने जा रहा था, लेकिन ऐसा लगता है कि आपने हर जगह अजगर 3.9 समाधान का उल्लेख किया है। :)
पायगॉन

196

यदि स्ट्रिंग ठीक हो गई है, तो आप बस उपयोग कर सकते हैं:

if line.startswith("Path="):
    return line[5:]

जो आपको स्ट्रिंग में स्थिति 5 पर सब कुछ देता है (एक स्ट्रिंग भी एक अनुक्रम है इसलिए ये अनुक्रम ऑपरेटर यहां भी काम करते हैं)।

या आप पहली बार में लाइन को विभाजित कर सकते हैं =:

if "=" in line:
    param, value = line.split("=",1)

फिर परम "पथ" है और मूल्य पहले = के बाद बाकी है।


3
विभाजन विधि के लिए +1, लेन (उपसर्ग) पर मैनुअल स्लाइसिंग की थोड़ी सी बदसूरती से बचा जाता है।
बोबिन्स

1
लेकिन यह भी फेंकता है यदि आपका इनपुट "कुछ = कुछ नहीं" के रूप में है।
दान ओल्सन

1
इसीलिए मैंने इस शर्त को सामने रखा है कि यदि स्ट्रिंग में "=" का उपयोग किया जाता है अन्यथा आप विभाजन के परिणाम की लंबाई के लिए भी परीक्षण कर सकते हैं () और यदि यह == 2 है।
MrTopf

7
जैसे डैन ओल्सन कहते हैं कि splitयदि कोई सीमांकक मौजूद नहीं है तो अपवाद को फेंकता है। partitionयह अधिक स्थिर है, यह एक तार को भी विभाजित करता है और हमेशा तीन तत्वों के टपल को पूर्व-, सीमांकक और बाद की सामग्री के साथ लौटाता है (जिनमें से कुछ हो सकता है ''यदि सीमांकक मौजूद नहीं था)। जैसे value = line.partition('='),।
एंडर्स जोहानसन

1
स्प्लिट एक अपवाद नहीं फेंकता है यदि सीमांकित मौजूद नहीं है, तो यह पूरी स्ट्रिंग के साथ एक सूची देता है। कम से कम अजगर 2.7
मैक्सिम

122

एक स्ट्रिंग से उपसर्ग निकालें

# ...
if line.startswith(prefix):
   return line[len(prefix):]

विभाजक की पहली घटना के माध्यम से विभाजित str.partition()

def findvar(filename, varname="Path", sep="=") :
    for line in open(filename):
        if line.startswith(varname + sep):
           head, sep_, tail = line.partition(sep) # instead of `str.split()`
           assert head == varname
           assert sep_ == sep
           return tail

कॉन्फ़िगर INI- तरह फ़ाइल को configParser के साथ

from ConfigParser import SafeConfigParser
config = SafeConfigParser()
config.read(filename) # requires section headers to be present

path = config.get(section, 'path', raw=1) # case-insensitive, no interpolation

अन्य विकल्प


1
चार के बजाय तीन स्थानों को इंडेंट करने का एक दुर्लभ कारण।
बॉब स्टीन

25
def remove_prefix(text, prefix):
    return text[len(prefix):] if text.startswith(prefix) else text

1
मुझे यह पसंद है क्योंकि आप "और टेक्स्ट" को "फ़ॉल्स" या "और कोई नहीं" या जो कुछ भी टाइप कर सकते हैं- आप इंगित करना चाहते हैं कि फ़ाइल में लाइन "पथ =" से शुरू नहीं हुई थी। व्यक्तिगत रूप से मैं अपने टर्नरी ऑपरेटरों को कोष्ठक के साथ घेरना चाहता हूं ताकि वे नेत्रहीन हो सकें।
DevPlayer

19

सामान्य रूप से टुकड़ा करने की क्रिया (सशर्त या गैर-सशर्त) के लिए मैं पसंद करता हूं जो एक सहयोगी ने हाल ही में सुझाव दिया था; खाली स्ट्रिंग के साथ प्रतिस्थापन का उपयोग करें। कोड को पढ़ने में आसान, कम कोड (कभी-कभी) और पात्रों की गलत संख्या को निर्दिष्ट करने का कम जोखिम। ठीक; मैं पायथन का उपयोग नहीं करता हूं, लेकिन अन्य भाषाओं में मैं इस दृष्टिकोण को पसंद करता हूं:

rightmost = full_path.replace('Path=', '', 1)

या - इस पोस्ट के लिए पहली टिप्पणी का पालन करने के लिए - यदि यह केवल तभी किया जाना चाहिए जब रेखा के साथ शुरू होता है Path:

rightmost = re.compile('^Path=').sub('', full_path)

उपरोक्त कुछ बातों का मुख्य अंतर यह है कि इसमें कोई "मैजिक नंबर" (5) शामिल नहीं है, और न ही ' 5' और स्ट्रिंग ' Path=' दोनों को निर्दिष्ट करने की आवश्यकता है , दूसरे शब्दों में, मैं एक कोड रखरखाव के इस दृष्टिकोण को पसंद करता हूं दृष्टिकोण।


यह काम नहीं करता है: 'c = Path = a'.replace ("Path =", "", 1) ->' c = a '।
jfs

3
यह "पथ =" से शुरू होने वाली स्ट्रिंग की मूल आवश्यकता को पूरा नहीं करता है।
पिल्ला

1
आप रेगेक्स कोड को बस से बदल सकते हैं rightmost = re.sub('^Path=', '', fullPath)compile()विधि का उद्देश्य चीजों को तेजी से बनाना है यदि आप संकलित वस्तु का पुन: उपयोग करते हैं, लेकिन जब से आप इसका उपयोग करने के बाद इसे फेंक देते हैं, वैसे भी यहां इसका कोई प्रभाव नहीं है। यह आमतौर पर वैसे भी इस अनुकूलन के बारे में चिंता करने योग्य नहीं है।
जिम ओल्डफील्ड

13

मैं popअनुक्रमण करना पसंद करता हूं [-1]:

value = line.split("Path=", 1).pop()

सेवा

value = line.split("Path=", 1)[1]
param, value = line.split("Path=", 1)

2
"मैजिक नंबर" के बिना अच्छा विकल्प। यह ध्यान देने योग्य है कि यह काम करता है क्योंकि startswithपहले से ही परीक्षण किया गया है इसलिए split"कुछ भी नहीं" को पहले और बाकी सब के बाद विभाजित करेगा। split("Path=", 1)अधिक सटीक है (उपसर्ग में बाद में आने वाले उपसर्ग के मामले में) लेकिन एक जादू की संख्या को फिर से बताता है।
quornian

1
(बहुत महत्वपूर्ण) पिछली टिप्पणी का छोटा संस्करण: यह केवल तभी काम करता है जब आप शुरुआती () के साथ परीक्षण करते हैं।
मार्क


5

कैसा रहेगा..

>>> line = r'path=c:\path'
>>> line.partition('path=')
('', 'path=', 'c:\\path')

यह त्रिक प्रमुख, विभाजक और पूंछ है


यह सभी मामलों में समान तरीके से काम नहीं करता है। यदि विभाजक मौजूद है, तो परिणाम तीसरा आइटम है। अन्यथा, परिणाम पहला आइटम है।
Ioannis Filippidis

5

सबसे आसान तरीका है जिसके बारे में मैं सोच सकता हूँ:

def find_path(i_file): 
    lines = open(i_file).readlines() 
    for line in lines: 
        if line.startswith("Path=") : 
            return line[5:]

स्लाइस नोटेशन पर एक त्वरित नोट, यह सामान्य के बजाय दो सूचकांकों का उपयोग करता है। पहला इंडेक्स उस अनुक्रम के पहले तत्व को इंगित करता है जिसे आप स्लाइस में शामिल करना चाहते हैं और आखिरी इंडेक्स उस आखिरी तत्व के तुरंत बाद का इंडेक्स है जिसे आप स्लाइस में शामिल करना चाहते हैं।
उदाहरण के लिए:

sequence_obj[first_index:last_index]

स्लाइस में first_indexऔर के बीच सभी तत्व last_indexशामिल हैं, first_indexऔर नहीं भी last_index। यदि पहला इंडेक्स छोड़ दिया जाता है, तो यह अनुक्रम की शुरुआत में चूक जाता है। यदि अंतिम सूचकांक को छोड़ दिया जाता है, तो इसमें अनुक्रम में अंतिम तत्व तक सभी तत्व शामिल होते हैं। नकारात्मक सूचकांकों की भी अनुमति है। विषय के बारे में अधिक जानने के लिए Google का उपयोग करें।


4
>>> import re

>>> p = re.compile(r'path=(.*)', re.IGNORECASE)

>>> path = "path=c:\path"

>>> re.match(p, path).group(1)
'c:\\path'

1. r''विंडोज पथ के लिए तारों का उपयोग करें । 2. re.match()कोई भी नहीं लौट सकता है
jfs

3

एक और सरल वन-लाइनर जिसका उल्लेख यहाँ नहीं किया गया है:

value = line.split("Path=", 1)[-1]

यह विभिन्न किनारे के मामलों के लिए भी ठीक से काम करेगा:

>>> print("prefixfoobar".split("foo", 1)[-1])
"bar"

>>> print("foofoobar".split("foo", 1)[-1])
"foobar"

>>> print("foobar".split("foo", 1)[-1])
"bar"

>>> print("bar".split("foo", 1)[-1])
"bar"

>>> print("".split("foo", 1)[-1])
""



1

यदि आप सूची बोध जानते हैं:

lines = [line[5:] for line in file.readlines() if line[:5] == "Path="]

एक सुझाव था कि संपादन line.startswith(...)10X तेज है। मेरे परीक्षण ने इसकी पुष्टि नहीं की। इसे बदलने के लिए खुश अगर सबूत कि सहायता प्रदान की जाती है।
मैथ्यू Schinckel

0

पॉप संस्करण काफी सही नहीं था। मुझे लगता है कि आप चाहते हैं:

>>> print('foofoobar'.split('foo', 1).pop())
foobar

0

बच के साथ रेगेक्स का उपयोग क्यों नहीं? ^एक पंक्ति के प्रारंभिक भाग से re.MULTILINEमेल खाता है और प्रत्येक पंक्ति पर मेल खाता है। re.escapeयह सुनिश्चित करता है कि मिलान सटीक है।

>>> print(re.sub('^' + re.escape('path='), repl='', string='path=c:\path\nd:\path2', flags=re.MULTILINE))
c:\path
d:\path2

0

निम्नलिखित कोड का प्रयास करें

if line.startswith("Path="): return line[5:]

1
आपके उत्तर और स्वीकृत उत्तर के बीच क्या अंतर है? मैं देखता हूं कि यह दूसरे उत्तर के पहले भाग में है।
पलकें

-1

मुझे यह लगता है कि आप वास्तव में क्या देख रहे हैं

    def findPath(i_file) :
        lines = open( i_file ).readlines()
        for line in lines :
            if line.startswith( "Path=" ):
                output_line=line[(line.find("Path=")+len("Path=")):]
                return output_line

-1

किसी फ़ंक्शन को लिखने के बिना, यह सूची के अनुसार विभाजित हो जाएगा, इस मामले में 'श्री। डॉ। डॉ। श्रीमती', विभाजन के बाद सब कुछ का चयन करें [1], फिर से विभाजित करें और जो भी तत्व पकड़ो। नीचे दिए गए मामले में, 'मॉरिस' वापस आ गया है।

re.split('Mr.|Dr.|Mrs.', 'Mr. Morgan Morris')[1].split()[1]

-1

यह अन्य उत्तरों के लिए तकनीक में बहुत समान है, लेकिन कोई दोहराए गए स्ट्रिंग संचालन के साथ, यह बताने की क्षमता है कि उपसर्ग था या नहीं, और अभी भी काफी पठनीय है:

parts = the_string.split(prefix_to_remove, 1):
    if len(parts) == 2:
        #  do things with parts[1]
        pass
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.