python - मैं पायथन में एक पिछली नई लाइन को कैसे हटा सकता हूं?




newline trailing (17)

rstrip इतने सारे स्तर पर chomp के समान काम नहीं करता है। chomp पढ़ें और देखें कि चॉम्प वास्तव में बहुत जटिल है।

हालांकि, मेरा मुख्य बिंदु यह है कि चॉम्प अधिकांश 1 लाइन समाप्त होने पर हटा देता है, जबकि rstrip जितना संभव हो उतना हटा देगा।

यहां आप सभी नईलाइनों को हटाने के लिए rstrip देख सकते हैं:

>>> 'foo\n\n'.rstrip(os.linesep)
'foo'

ठेठ पर्ल चॉम्प उपयोग का एक बहुत करीब अनुमान re.sub के साथ पूरा किया जा सकता है, इस तरह:

>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'

पर्ल के chomp फ़ंक्शन के पाइथन समकक्ष क्या है, जो एक स्ट्रिंग के अंतिम चरित्र को हटा देता है यदि यह एक नई लाइन है?


आप line = line.rstrip('\n') उपयोग कर सकते हैं। यह स्ट्रिंग के अंत से सभी न्यूलाइन को पट्टी कर देगा, सिर्फ एक ही नहीं।


एंड-ऑफ-लाइन (ईओएल) अक्षरों को पट्टी करने का कैननिकल तरीका किसी भी पीछे \ r या \ n को हटाने वाली स्ट्रिंग rstrip () विधि का उपयोग करना है। मैक, विंडोज़, और यूनिक्स ईओएल अक्षरों के उदाहरण यहां दिए गए हैं।

>>> 'Mac EOL\r'.rstrip('\r\n')
'Mac EOL'
>>> 'Windows EOL\r\n'.rstrip('\r\n')
'Windows EOL'
>>> 'Unix EOL\n'.rstrip('\r\n')
'Unix EOL'

Rstrip के पैरामीटर के रूप में '\ r \ n' का उपयोग करना मतलब है कि यह '\ r' या '\ n' के किसी भी पिछला संयोजन को मिटा देगा। यही कारण है कि यह उपरोक्त सभी तीन मामलों में काम करता है।

यह बारीकियों दुर्लभ मामलों में मायने रखता है। उदाहरण के लिए, मुझे एक बार एक टेक्स्ट फ़ाइल को संसाधित करना पड़ा जिसमें एचएल 7 संदेश था। एचएल 7 मानक को अपने ईओएल चरित्र के रूप में पीछे की ओर 'आर' की आवश्यकता होती है। जिस विंडोज मशीन पर मैं इस संदेश का उपयोग कर रहा था, उसने अपना '\ r \ n' ईओएल चरित्र जोड़ा था। इसलिए, प्रत्येक पंक्ति का अंत '\ r \ r \ n' जैसा दिखता था। Rstrip ('\ r \ n') का उपयोग करने से पूरे '\ r \ r \ n' को हटा दिया गया था जो मैं नहीं चाहता था। उस स्थिति में, मैंने बस इसके बजाय पिछले दो पात्रों को काट दिया।

ध्यान दें कि पर्ल के chomp फ़ंक्शन के विपरीत, यह स्ट्रिंग के अंत में सभी निर्दिष्ट वर्णों को स्ट्रिप करेगा, केवल एक ही नहीं:

>>> "Hello\n\n\n".rstrip("\n")
"Hello"

ऐसा लगता है कि पर्ल के chomp लिए एक आदर्श एनालॉग नहीं है। विशेष रूप से, rstrip बहु-वर्ण न्यूलाइन डिलीमीटर जैसे \r\n संभाल नहीं सकता है। हालांकि, स्प्लिटलाइन यहां बताई गई है । एक अलग प्रश्न पर मेरे उत्तर के बाद, आप स्ट्रिंग s से सभी न्यूलाइनों को हटाने / बदलने के लिए join और स्प्लिटललाइन को जोड़ सकते हैं:

''.join(s.splitlines())

निम्नलिखित बिल्कुल पीछे की रेखा को हटा देता है (जैसा कि chomp होगा, मुझे विश्वास है)। keepends लिए keepends तर्क के रूप में True पारित करना delimiters को बनाए रखने। फिर, अंतिम "लाइन" पर डिलीमीटर को हटाने के लिए स्प्लिटलाइन को फिर से बुलाया जाता है:

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''

तीन प्रकार के लाइन एंडिंग हैं जिन्हें हम आम तौर पर सामना करते हैं: \n , \r और \r\nre.sub में एक साधारण सरल अभिव्यक्ति, अर्थात् r"\r?\n?$" , उन सभी को पकड़ने में सक्षम है।

(और हमें सभी को पकड़ना होगा , क्या मैं सही हूँ?)

import re

re.sub(r"\r?\n?$", "", the_text, 1)

आखिरी तर्क के साथ, हम कुछ हद तक chomp की नकल, अवसरों की संख्या को एक में बदल दिया। उदाहरण:

import re

text_1 = "hellothere\n\n\n"
text_2 = "hellothere\n\n\r"
text_3 = "hellothere\n\n\r\n"

a = re.sub(r"\r?\n?$", "", text_1, 1)
b = re.sub(r"\r?\n?$", "", text_2, 1)
c = re.sub(r"\r?\n?$", "", text_3, 1)

... जहां a == b == c True


ध्यान दें कि rstrip बिल्कुल पर्ल के chomp () की तरह कार्य नहीं करता है क्योंकि यह स्ट्रिंग को संशोधित नहीं करता है। वह है, पर्ल में:

$x="a\n";

chomp $x

परिणाम $x में "a"

लेकिन पायथन में:

x="a\n"

x.rstrip()

इसका मतलब यह होगा कि x का मान अभी भी "a\n" । यहां तक ​​कि x=x.rstrip() हमेशा एक ही परिणाम नहीं देता है, क्योंकि यह स्ट्रिंग के अंत से सभी व्हाइटस्पेस को स्ट्रिप्स करता है, न कि केवल एक नई लाइन पर।


मुझे इटेटरेटर के माध्यम से चोम्प्ड लाइनों को प्राप्त करने में सक्षम होना सुविधाजनक लगता है, जिस तरह से आप फ़ाइल ऑब्जेक्ट से अन-कॉम्प्ड लाइन प्राप्त कर सकते हैं। आप निम्न कोड के साथ ऐसा कर सकते हैं:

def chomped_lines(it):
    return map(operator.methodcaller('rstrip', '\r\n'), it)

नमूना उपयोग:

with open("file.txt") as infile:
    for line in chomped_lines(infile):
        process(line)

मैं अपने नियमित अभिव्यक्ति आधारित उत्तर को एक दूसरे उत्तर की टिप्पणियों में पहले पोस्ट किया गया हूं। मुझे लगता है कि re का उपयोग str.rstrip तुलना में इस समस्या का एक स्पष्ट और स्पष्ट समाधान है।

>>> import re

यदि आप एक या अधिक पिछला न्यूलाइन वर्ण निकालना चाहते हैं:

>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'

यदि आप हर जगह न्यूलाइन वर्णों को हटाना चाहते हैं (केवल पीछे नहीं):

>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'

यदि आप केवल 1-2 पिछला न्यूलाइन वर्ण निकालना चाहते हैं (यानी, \r , \n , \r\n , \n\r , \r\r , \n\n )

>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r\n')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n')
'\nx'

मुझे लगता है कि ज्यादातर लोग वास्तव में यहां क्या चाहते हैं, एक पिछली न्यूलाइन चरित्र की केवल एक घटना को हटाना है, या तो \r\n या \n और कुछ भी नहीं।

>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n\n', count=1)
'\nx\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n\r\n', count=1)
'\nx\r\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n', count=1)
'\nx'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n', count=1)
'\nx'

(द?: एक गैर कैप्चरिंग समूह बनाना है।)

(वैसे यह नहीं है '...'.rstrip('\n', '').rstrip('\r', '') जो इस थ्रेड पर ठोकरें दूसरों के लिए स्पष्ट नहीं हो सकता है। str.rstrip जितना संभव हो सके पीछे के अक्षरों के रूप में स्ट्रिप्स करता है, इसलिए foo\n\n\n जैसी स्ट्रिंग के परिणामस्वरूप foo का झूठा सकारात्मक परिणाम होगा, जबकि आप एकल पीछे हटने के बाद अन्य न्यूलाइन को संरक्षित करना चाहते हैं।)


मैं पायथन में प्रोग्राम नहीं करता हूं, लेकिन मैं python.org पर python.org के लिए एसआरस्ट्रिप ("\ r \ n") की वकालत करते हुए एक FAQ पर आया था।


यदि आप गति के बारे में चिंतित हैं (कहें कि आपके पास स्ट्रिंग्स की लूओंग सूची है) और आप न्यूलाइन चार की प्रकृति को जानते हैं, स्ट्रिंग स्लाइसिंग वास्तव में rstrip से तेज है। इसे स्पष्ट करने के लिए एक छोटा सा परीक्षण:

import time

loops = 50000000

def method1(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string[:-1]
    t1 = time.time()
    print('Method 1: ' + str(t1 - t0))

def method2(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string.rstrip()
    t1 = time.time()
    print('Method 2: ' + str(t1 - t0))

method1()
method2()

आउटपुट:

Method 1: 3.92700004578
Method 2: 6.73000001907

यह लाइन टर्मिनेटर के लिए "\ n" सरणी के लिए बिल्कुल perl के chomp (सरणी पर शून्य व्यवहार) दोहराएगा:

def chomp(x):
    if x.endswith("\r\n"): return x[:-2]
    if x.endswith("\n"): return x[:-1]
    return x

(ध्यान दें: यह 'जगह में' स्ट्रिंग को संशोधित नहीं करता है; यह अतिरिक्त पिछला सफेद स्थान नहीं लेता है; खाते में \ r \ n लेता है)


विधि rstrip() प्रयास करें (दस्तावेज़ पाइथन 2 और पायथन 3 देखें )

>>> 'test string\n'.rstrip()
'test string'

पाइथन की rstrip() विधि डिफ़ॉल्ट रूप से सभी प्रकार के पिछली सफेद rstrip() स्ट्रिप्स करती है , न कि केवल एक नई लाइन के रूप में पर्ल chomp साथ करता है।

>>> 'test string \n \r\n\n\r \n\n'.rstrip()
'test string'

केवल नई लाइनों को पट्टी करने के लिए:

>>> 'test string \n \r\n\n\r \n\n'.rstrip('\n')
'test string \n \r\n\n\r '

lstrip() और strip() विधियों भी हैं:

>>> s = "   \n\r\n  \n  abc   def \n\r\n  \n  "
>>> s.strip()
'abc   def'
>>> s.lstrip()
'abc   def \n\r\n  \n  '
>>> s.rstrip()
'   \n\r\n  \n  abc   def'

सभी को पकड़ो:

line = line.rstrip('\r|\n')

पायथन के दस्तावेज में एक उदाहरण बस line.strip() का उपयोग करता है।

पर्ल का chomp फ़ंक्शन केवल एक स्ट्रिंग के अंत से एक लाइनबैक अनुक्रम को हटा देता है, अगर वास्तव में वहां होता है।

यहां बताया गया है कि मैं पाइथन में ऐसा करने की योजना कैसे बना रहा हूं, अगर process संकल्पनात्मक रूप से वह कार्य है जिसे मुझे इस फ़ाइल से प्रत्येक पंक्ति के लिए कुछ उपयोगी करने के लिए आवश्यक है:

import os
sep_pos = -len(os.linesep)
with open("file.txt") as f:
    for line in f:
        if line[sep_pos:] == os.linesep:
            line = line[:sep_pos]
        process(line)

"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'

या आप हमेशा regexps के साथ geekier मिल सकता है :)

मज़े करो!


>>> '   spacious   '.rstrip()
'   spacious'
>>> "AABAA".rstrip("A")
  'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
   ''
>>> "ABCABBA".rstrip("AB")
   'ABC'

s = s.rstrip()

स्ट्रिंग s के अंत में सभी न्यूलाइन हटा देंगे। असाइनमेंट की आवश्यकता है क्योंकि मूल स्ट्रिंग को संशोधित करने के बजाय rstrip एक नई स्ट्रिंग देता है।





trailing