2008-10-08 5 views
11

क्या यह एक लाइन में ऐसा करने का कोई तरीका है?क्या स्ट्रिंग के दोनों किनारों से सफेद जगह को ट्रिम करने के लिए एक पर्ल-संगत नियमित अभिव्यक्ति है?

$x =~ s/^\s+//; 
$x =~ s/\s+$//; 

दूसरे शब्दों में, एक स्ट्रिंग से सभी प्रमुख और पिछली सफेद जगह हटा दें।

+2

"ट्रिम" स्ट्रिंग के दोनों किनारों से व्हाइटस्पेस को हटाने के लिए सामान्य नाम है। क्या आप: $ title = ~ s/remove/trim/ – Kip

+0

मैं "pcre" टैग को हटा रहा हूं क्योंकि यह सी रेगेक्स लाइब्रेरी का नाम है (वह जो PHP के preg फ़ंक्शन को सशक्त करता है), और यह स्पष्ट रूप से नहीं है कि इसका उपयोग कैसे किया जा रहा है यहाँ। –

उत्तर

26
$x =~ s/^\s+|\s+$//g; 

या

s/^\s+//, s/\s+$// for $x; 
+0

विकल्प 2: यह एक अच्छी चाल है, लेकिन वास्तव में सवाल का जवाब नहीं देता है: डी – ephemient

+2

यह प्रश्न का उत्तर कैसे नहीं देता है? यह सिंगल रेगेक्स के प्रदर्शन चूसने के विकल्प के बिना दोनों तरफ से ट्रिम कर रहा है। –

+0

एस/^ \ एस * (। *?) \ S */\ 1 /; उन दो विकल्पों में से किसी एक से अधिक विकल्पों का प्रयास करना है –

2

$ x = ~/s (^ \ s +) | (\ रों + $) // छ;

+1

इस तरह मैं हमेशा ऐसा करता हूं .. अब तक का सबसे आसान लगता है। – Kip

+0

हाँ, और यह कहता है कि इसका क्या अर्थ है - सफेद स्थान शुरू करने या वैश्विक स्तर पर कुछ भी नहीं के साथ सफेद स्थान समाप्त करना। –

+2

कैप्चरिंग पैरों का उपयोग या आवश्यकता नहीं होती है - आम तौर पर आप उन्हें समूहबद्ध माता-पिता (?: ...) के साथ प्रतिस्थापित कर सकते हैं, लेकिन इस मामले में प्राथमिकता अच्छी तरह से काम करती है और आप पूरी तरह से कोष्ठक को हटा सकते हैं। – ephemient

-2
$x =~ s/^\s*(.*?)\s*$/$1/; 
+0

प्रतिस्थापन स्ट्रिंग में $ 1 के बजाय \ 1 का उपयोग करके पर्ल में निराश किया गया है, 'perldoc perlre' में "1 $ बनाम $ 1" पर चेतावनी देखें। – ephemient

+0

चूंकि क्वांटिफायर लालची हैं, इसलिए आपको मिलान करने के बाद [^ \ s] जैसे कुछ कहने की आवश्यकता नहीं है। इसके अलावा, [^ \ s] के बजाय, आप बस \ S कह सकते हैं। पूंजीकृत संस्करण पूरक चरित्र वर्ग हैं। :) –

+0

ब्रायन: हाँ, लेकिन केवल अगर मैं बना देता हूं। * असभ्य। – Lev

0
s/^\s*(\S*\S)\s*$/$1/ 
+0

प्रतिस्थापन स्ट्रिंग में $ 1 के बजाय \ 1 का उपयोग करके पर्ल में निराश किया गया है, 'perldoc perlre' में "1 $ बनाम $ 1" पर चेतावनी देखें। – ephemient

+0

आप सही हैं, मैं इसे सही कर दूंगा। –

+0

यहां समस्या यह है कि आपको स्ट्रिंग में कम से कम 2 गैर-व्हाइटस्पेस वर्णों की आवश्यकता होती है, या यह काम नहीं करेगा। – bart

30

मेरा पहला सवाल यह है कि ... क्यों? मुझे आपके द्वारा शुरू किए गए रेगेक्सप की तुलना में किसी भी एकल-रेगेक्स समाधान को और अधिक पठनीय नहीं दिखता है। और वे निश्चित रूप से कहीं भी तेजी से पास नहीं हैं।

#!/usr/bin/perl 

use strict; 
use warnings; 

use Benchmark qw(:all); 

my $a = 'a' x 1_000; 

my @x = (
     " $a ", 
     "$a ", 
     $a, 
     " $a" 
     ); 

cmpthese(-5, 
     { 
      single => sub { 
       for my $s (@x) 
       { 
        my $x = $s; 
        $x =~ s/^\s+|\s+$//g; 
       } 
      }, 
      double => sub { 
       for my $s (@x) 
       { 
        my $x = $s; 
        $x =~ s/^\s+//; 
        $x =~ s/\s+$//; 
       } 
      }, 
      trick => sub { 
       for my $s (@x) 
       { 
        my $x = $s; 
        s/^\s+//, s/\s+$// for $x; 
       } 
      }, 
      capture => sub { 
       for my $s (@x) 
       { 
        my $x = $s; 
        $x =~ s/\A\s*(.*?)\s*\z/$1/ 
       } 
      }, 
      kramercap => sub { 
       for my $s (@x) 
       { 
        my $x = $s; 
        ($x) = $x =~ /^\s*(.*?)\s*$/ 
       } 
      }, 
     } 
     ); 

की मेरी मशीन पर परिणाम देता है:

 
      Rate single capture kramercap  trick double 
single  2541/s  --  -12%  -13%  -96%  -96% 
capture 2902/s  14%  --  -0%  -95%  -96% 
kramercap 2911/s  15%  0%  --  -95%  -96% 
trick  60381/s  2276%  1981%  1974%  --  -7% 
double 65162/s  2464%  2145%  2138%  8%  -- 

संपादित: runrig सही है, लेकिन बहुत कम परिवर्तन करने के लिए। मैंने संशोधन से पहले स्ट्रिंग की प्रतिलिपि बनाने के लिए कोड अपडेट किया है, जो निश्चित रूप से चीजों को धीमा कर देता है। मैंने लंबे स्ट्रिंग का उपयोग करने के लिए एक और जवाब में ब्रायन डी फोय के सुझाव को भी ध्यान में रखा (हालांकि एक लाख ओवरकिल की तरह लग रहा था)। हालांकि, यह भी सुझाव देता है कि आप चाल शैली चुनने से पहले, आप समझते हैं कि आपकी स्ट्रिंग लंबाई क्या है - चाल के फायदे छोटे तारों से कम हो जाते हैं। मैंने परीक्षण की है कि सभी लंबाई में, डबल जीतता है। और यह आंखों पर अभी भी आसान है।

+0

आप मान रहे हैं कि वह पर्ल में ऐसा कर रहा है, और शायद यह मामला नहीं हो सकता है। "पर्ल-संगत" हमेशा मेरे लिए लाल झंडे उठाता है। –

+0

सच - यह पर्ल और पिक टैग दोनों को देखने में थोड़ा उलझन में है ... – Tanktalus

+0

आपके सभी "परीक्षण" पहले पुनरावृत्ति पर @x बदल देंगे। इसलिए कोई भी परीक्षण नहीं कर रहा है जो आप सोचते हैं। आपको अपने subs में @x कॉपी करने की आवश्यकता है। और डबल समाधान में, इसे लूप में लपेटें, बस "@x" के लिए उपयोग करें। – runrig

5

विवादास्पद से बहस, यह बिल्कुल क्यों? उपरोक्त सभी समाधान "सही" हैं, जिसमें वे एक पास में स्ट्रिंग के दोनों किनारों से व्हाइटस्पेस ट्रिम करते हैं, लेकिन कोई भी बहुत पठनीय नहीं है (शायद this one की अपेक्षा करें)। जब तक अपने कोड के लिए दर्शकों को विशेषज्ञ स्तर के पर्ल कोडर के शामिल है ऊपर उम्मीदवारों में से प्रत्येक क्या वे (वैसे भी शायद एक अच्छा विचार है) कर का वर्णन एक टिप्पणी होनी चाहिए। इसके विपरीत, इन दो पंक्तियों lookaheads, वाइल्डकार्ड, midichlorines या कुछ भी है कि मध्यम अनुभव के एक प्रोग्रामर के लिए तुरंत स्पष्ट नहीं है का उपयोग किए बिना एक ही बात को पूरा:

$string =~ s/^\s+//; 
$string =~ s/\s+$//; 

वहाँ (बेशक) एक प्रदर्शन हिट है, लेकिन के रूप में है जब तक आप कुछ microseconds निष्पादन पर चिंतित नहीं हैं, तब तक अतिरिक्त पठनीयता इसके लायक होगी। IMHO।

+0

प्रदर्शन हिट? कौन बहस कर सकता है? यह सूचीबद्ध किसी भी अन्य समाधान के रूप में दोगुनी से अधिक तेजी से है। – Tanktalus

+0

पर्याप्त मेला, मैंने कोड को बेंचमार्क नहीं किया क्योंकि मैं देर से दोपहर के भोजन के लिए दरवाजा बाहर निकलना चाहता था। यह जानकर खुशी हुई कि कोई प्रदर्शन हिट नहीं है। – Logan

+0

पर्ल विशेषज्ञ? मेरे लर्निंग पर्ल पाठ्यक्रम में लोग दूसरे दिन के अंत तक इन सभी समाधानों को समझेंगे। –

8

अजीब बात है तो आप इस ऊपर लाने चाहिए!

मैं हाल ही में an article analyzing the performance of twelve (!) different trim implementations पढ़ें।

हालांकि लेख विशेष रूप से जावास्क्रिप्ट regex कार्यान्वयन का उपयोग करता है, यह पर्ल सिंटैक्स का उपयोग करता है, तो मुझे लगता है कि इस चर्चा के अनुरूप है।

8

Tanktalus बहुत छोटे तार के लिए एक बेंचमार्क दिखाता है, लेकिन के रूप में तार बड़ा पाने के लिए समस्या बदतर हो।

my $a = 'a' x 1_000_000; 

my @x = (
    " $a ", 
    "$a ", 
    $a, 
    " $a" 
); 

मैं ये परिणाम प्राप्त: अपने कोड में, मैं शीर्ष भाग बदल स्ट्रिंग बड़ा हो जाता है

  Rate single capture trick double 
single 2.09/s  -- -12% -98% -98% 
capture 2.37/s  13%  -- -98% -98% 
trick 96.0/s 4491% 3948%  --  -0% 
double 96.4/s 4512% 3967%  0%  -- 

के रूप में, "चाल" और "डबल" लगभग एक ही हैं, और का उपयोग कर आम समाधान जो ज्यादातर लोग जाते हैं, "सिंगल" (मेरे साथ, क्योंकि मैं उस आदत को तोड़ नहीं सकता हूं, भले ही मुझे यह पता चले), वास्तव में चूसना शुरू कर देता है।

जब भी आप एक बेंचमार्क देखते हैं, तो यह सोचें कि यह आपको क्या बता रहा है। यह देखने के लिए कि क्या आप इसे समझते हैं, डेटा बदलें और पुनः प्रयास करें। सरणी लंबे, स्केलर्स बड़ा, और इतने पर बनाओ। लूप, ग्रीप्स, या रेगेक्स को स्टार्ट, मध्य और अंत में सामान ढूंढें। देखें कि नए परिणाम आपकी भविष्यवाणी से मेल खाते हैं या नहीं। यह पता लगाएं कि प्रवृत्ति क्या है। क्या प्रदर्शन बेहतर और बेहतर हो जाता है, एक सीमा तक पहुंचता है, फिर चोटी में गिरावट शुरू होती है, या कुछ और?

1

मैं आमतौर पर इस तरह यह कार्य करें:

प्रमुख स्थानों और पीछे वाले स्पेस के बीच
($foo) = $foo =~ /^\s*(.*?)\s*$/; 

सब कुछ वर्गीकृत किया और दिया जाता है, तो मैं वही पुरानी चर को असाइन कर सकें।

-1
$var1 =~ s/(^\s*)(.*?)(\s*$)+/$2/; 
संबंधित मुद्दे