2010-09-22 20 views
5

मैं एक पर्ल फ़ाइल संपादित कर रहा हूं, लेकिन मुझे यह regexp तुलना नहीं समझती है। क्या कोई इसे मुझे समझा सकता है?

if ($lines =~ m/(.*?):(.*?)$/g) { } .. 

यहां क्या होता है? $lines एक टेक्स्ट फ़ाइल से एक लाइन है।

+0

के रूप में लिखा गया है पहले की तरह लग रहा '(। *?)' हमेशा रिक्त स्ट्रिंग पर मेल खाएगी। –

+1

हमेशा नहीं। यह पहले कॉलन तक सभी पात्रों से मेल खाएगा। – CanSpice

उत्तर

11
इसे तोड़

भागों में:

$lines =~ m/ (.*?)  # Match any character (except newlines) 
         # zero or more times, not greedily, and 
         # stick the results in $1. 
      :   # Match a colon. 
      (.*?)  # Match any character (except newlines) 
         # zero or more times, not greedily, and 
         # stick the results in $2. 
      $   # Match the end of the line. 
      /gx; 

तो, यह ":" तरह तार के अनुरूप होगा (यह शून्य वर्ण, तो एक पेट, तो लाइन के अंत से पहले शून्य से मेल खाता है, $1 और $2 खाली हैं स्ट्रिंग्स), या "abc:" ($1 = "abc", $2 एक खाली स्ट्रिंग है), या "abc:def:ghi" ($1 = "abc" और $2 = "def:ghi")।

और यदि आप किसी ऐसी रेखा में गुजरते हैं जो मेल नहीं खाता है (ऐसा लगता है कि स्ट्रिंग में कोलन नहीं होता है), तो यह ब्रैकेट के भीतर कोड को संसाधित नहीं करेगा। लेकिन यदि यह मेल खाता है, तो ब्रैकेट के भीतर कोड विशेष $1 और $2 चर का उपयोग और प्रक्रिया कर सकता है (कम से कम, अगली नियमित अभिव्यक्ति तब तक दिखाई देगी जब ब्रैकेट में कोई होता है)।

1

(.*?) किसी भी पात्र को कैप्चर करता है, लेकिन उनमें से कुछ जितना संभव हो।

तो यह <something>:<somethingelse><end of line> की तरह पैटर्न के लिए लग रहा है, और एक से अधिक स्ट्रिंग में : हैं, पहले एक <something> और <somethingelse> के बीच भाजक के रूप में इस्तेमाल किया जाएगा।

2

वह पंक्ति $lines पर रेगेक्स m/(.*?):(.*?)$/g के साथ एक नियमित अभिव्यक्ति मैच करने के लिए कहती है। यदि $lines और false में कोई मिलान नहीं मिल पाता है तो यह true प्रभावी ढंग से वापस आ जाएगा।

=~ ऑपरेटर के बारे में स्पष्टीकरण:

बाइनरी "= ~" एक पैटर्न मैच के लिए एक अदिश अभिव्यक्ति बांधता है। कुछ परिचालन डिफ़ॉल्ट रूप से स्ट्रिंग $ _ को खोज या संशोधित करें। यह ऑपरेटर किसी अन्य स्ट्रिंग पर ऑपरेशन कार्य के बनाता है। सही तर्क एक खोज पैटर्न, प्रतिस्थापन, या लिप्यंतरण है। बाएं तर्क खोजा जाना चाहिए, प्रतिस्थापित, या डिफ़ॉल्ट $ _ के बजाय लिप्यंतरित किया गया है। जब स्केलर संदर्भ में उपयोग किया जाता है, तो आमतौर पर वापसी मूल्य ऑपरेशन की सफलता को इंगित करता है।

regex ही है:

m/ #Perform a "match" operation 
(.*?) #Match zero or more repetitions of any characters, but match as few as possible (ungreedy) 
:  #Match a literal colon character 
(.*?) #Match zero or more repetitions of any characters, but match as few as possible (ungreedy) 
$  #Match the end of string 
/g #Perform the regex globally (find all occurrences in $line) 

तो अगर कि regex के खिलाफ $lines मैच, यह सशर्त भाग में जाना होगा, अन्यथा यह false हो जाएगा और यह छोड़ देगा।

9

रेगेक्स को समझने में मदद करने के लिए एक उपकरण है: YAPE::Regex::Explain

use strict; 
use warnings; 
use YAPE::Regex::Explain; 

my $re = qr/(.*?):(.*?)$/; 
print YAPE::Regex::Explain->new($re)->explain(); 

__END__ 

The regular expression: 

(?-imsx:(.*?):(.*?)$) 

matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
    :      ':' 
---------------------------------------------------------------------- 
    (      group and capture to \2: 
---------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
---------------------------------------------------------------------- 
)      end of \2 
---------------------------------------------------------------------- 
    $      before an optional \n, and the end of the 
          string 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

भी perldoc perlre देखें:

g संशोधक, जो यहाँ की जरूरत नहीं है की उपेक्षा।

+1

यह बहुत साफ है! –

3

यह किसी ऐसे व्यक्ति द्वारा लिखा गया था जो या तो नियमित अभिव्यक्तियों के बारे में बहुत कुछ जानता है या $' और $` चर के बारे में पर्याप्त नहीं है।

इस सकता है

if ($lines =~ /:/) { 
    ... # use $` ($PREMATCH) instead of $1 
    ... # use $' ($POSTMATCH) instead of $2 
} 

या

if (($var1,$var2) = split /:/, $lines, 2 and defined($var2)) { 
    ... # use $var1, $var2 instead of $1,$2 
} 
+1

यदि आप///का उपयोग करना चाहते हैं, तो/p ध्वज और $ {^ PREMATCH} और $ {^ POSTMATCH} चर का उपयोग पर्ल 5.10 से करें। मैं विभाजन करना पसंद करूंगा, हालांकि, वास्तव में यह हो रहा है। –

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