2009-07-15 16 views
8

मेरा प्रोग्राम अन्य प्रोग्राम स्रोत कोड और प्रयुक्त SQL क्वेरी के बारे में जानकारी एकत्रित करता है। मुझे सबस्ट्रिंग प्राप्त करने में समस्या है।पर्ल में, मैं एक regex से मिलान किए गए सबस्ट्रिंग कैसे प्राप्त कर सकता हूं?

... 
$line = <FILE_IN>; 
until(($line =~m/$values_string/i && $line !~m/$rem_string/i) || eof) 
{ 
    if($line =~m/ \S{2}DT\S{3}/i) 
    { 

    # here I wish to get (only) substring that match to pattern \S{2}DT\S{3} 
    # (7 letter table name) and display it. 
     $line =~/\S{2}DT\S{3}/i; 
     print $line."\n"; 
... 

परिणामस्वरूप प्रिंट पूरी लाइन प्रिंट करता है और एक सबस्ट्रिंग की अपेक्षा नहीं करता है। मैंने अलग-अलग दृष्टिकोण की कोशिश की, लेकिन मैं शायद ही कभी पर्ल का उपयोग करता हूं और शायद बुनियादी अवधारणा त्रुटि करता हूं। (लाइन में tablename की स्थिति तय नहीं है। एक और समस्या कई घटनाओं है I.e ... [चुनें * AADTTAB, बीबीडीटीटीएबी, ...])। मैं उस सबस्ट्रिंग को कैसे प्राप्त कर सकता हूं?

+0

आप सभी त्वरित और विभिन्न दृष्टिकोण के लिए धन्यवाद। मैंने कल और आज सुबह और/लेकिन केवल $ और मेरे लिए काम करने की कोशिश की। इसके लिए भी धन्यवाद (सख्त उपयोग करें; चेतावनियों का उपयोग करें;) सुराग जिसने मुझे अपनी सुधार शैली दिखायी। आज मैं यह भी महसूस मैं सूचित नहीं किया था कि मैं खिड़कियों के तहत काम (मेरी मोती है: इस के लिए MSWin32-86-बहु धागा कॉपीराइट 1987-2005 बनाया, लैरी वॉल बाइनरी द्वारा प्रदान की निर्माण 813 [148,120] पर्ल, v5.8.7 है ActiveState www.ActiveState.com जून 6 2005 13:36:37 बनाया गया)। एक बार फिर धन्यवाद। –

+3

मैं थोड़ा चिढ़ के बाद मेरे चेहरे में "अज्ञान एक आनंद है" था, लेकिन यह मुझे पुश करने के लिए ... ठीक है ... बस अब कहते हैं कि मैं क्या 'पर कब्जा समूह' 'कोष्ठक/कोष्ठक का मतलब जानते हैं और यह वास्तव में काम करता है। कृपया टिप्पणी न करें मैं पहले से ही मूर्खतापूर्ण महसूस करता हूं। बीटीडब्लू, क्या कोई भी वैश्विक वोट देने के लिए वैश्विक वोट समर्थक है - मुझे नहीं पता - मोती? ;) –

+0

पहले से ही पर्ल नाम की एक भाषा थी, जब लैरी वॉल नाम की तलाश में गई थी। –

उत्तर

8

यदि यह FROM का पालन करता है तो पैटर्न से मिलान करना बेहतर होगा। मुझे लगता है कि टेबल नाम पूरी तरह से ASCII अक्षरों के होते हैं। उस स्थिति में, यह कहना सर्वोत्तम है कि आप क्या चाहते हैं। जिस तरह से दो टिप्पणियों के साथ, ध्यान दें कि सूची संदर्भ में एक सफल कैप्चरिंग रेगेक्स मैच मिलान किए गए सबस्ट्रिंग को वापस देता है।

#!/usr/bin/perl 

use strict; 
use warnings; 

my $s = 'select * from aadttab, bbdttab'; 
if (my ($table) = $s =~ /FROM ([A-Z]{2}DT[A-Z]{3})/i) { 
    print $table, "\n"; 
} 
__END__ 

आउटपुट:

C:\Temp> s 
aadttab 

आपके सिस्टम पर perl के संस्करण के आधार पर, आप एक नामित कब्जा समूह है जो पूरी बात को आसान बना सकता उपयोग करने के लिए पढ़ने में सक्षम हो सकता है:

if ($s =~ /FROM (?<table>[A-Z]{2}DT[A-Z]{3})/i) { 
    print $+{table}, "\n"; 
} 

perldoc perlre देखें।

20

ब्रांड्स के साथ समूह का उपयोग करें और पहले समूह को स्टोर करें।

if($line =~ /(\S{2}DT\S{3})/i) 
{ 
    my $substring = $1; 
} 

उपरोक्त कोड पहले तालिका नाम को खींचने की तत्काल समस्या को हल करता है। हालांकि, सवाल यह भी पूछा कि सभी टेबल नामों को कैसे निकाला जाए। तो:

# FROM\s+  match FROM followed by one or more spaces 
# (.+?)  match (non-greedy) and capture any character until... 
# (?:x|y)  match x OR y - next 2 matches 
# [^,]\s+[^,] match non-comma, 1 or more spaces, and non-comma 
# \s*;  match 0 or more spaces followed by a semi colon 
if($line =~ /FROM\s+(.+?)(?:[^,]\s+[^,]|\s*;)/i) 
{ 
    # $1 will be table1, table2, table3 
    my @tables = split(/\s*,\s*/, $1); 
    # delim is a space/comma 
    foreach(@tables) 
    { 
    # $_ = table name 
    print $_ . "\n"; 
    } 
} 

परिणाम:

हैं $ लाइन = "का चयन करें * AADTTAB, BBDTTAB से,"

आउटपुट:

AADTTAB 
BBDTTAB 

$ लाइन = यदि "AADTTAB से चुनें *,"

आउटपुट:

AADTTAB 

पर्ल संस्करण: MSWin32-86-बहु धागा

3

एक कैप्चरिंग समूह उपयोग के लिए बनाया गया v5.10.0:

$line =~ /(\S{2}DT\S{3})/i; 
my $substr = $1; 
+2

मिलान चर का उपयोग करने से पहले मैच सफल हुआ या नहीं। –

7

कोष्ठक आप हिस्सा हड़पने देंगे विशेष चर में रेगेक्स का: $ 1, $ 2, $ 3 ... तो:

$line = ' abc andtabl 1234'; 
if($line =~m/ (\S{2}DT\S{3})/i) { 
    # here I wish to get (only) substring that match to pattern \S{2}DT\S{3}  
    # (7 letter table name) and display it.  
    print $1."\n"; 
} 
-1

$& अंतिम पैटर्न मिलान से मेल खाने वाली स्ट्रिंग शामिल है।

उदाहरण:

$str = "abcdefghijkl"; 
$str =~ m/cdefg/; 
print $&; 
# Output: "cdefg" 

तो तुम जैसे

if($line =~m/ \S{2}DT\S{3}/i) { 
    print $&."\n"; 
} 

चेतावनी कुछ कर सकते हैं:

आप अपने कोड में $& का उपयोग करते हैं इसे नीचे सभी नमूने का मिलान धीमी हो जाएगी।

+1

$ और $ और $ 'का उपयोग करने से बचें, वे आपके कोड में सभी regexes पर प्रदर्शन दंड का कारण बनते हैं। अधिक जानकारी के लिए perlre (http://perldoc.perl.org/perlre.html) देखें। – daotoad

+1

बस आपके कोड में कहीं भी '$ &' का उल्लेख है, सभी रेगेक्स को धीमा कर देगा। इससे कोई फर्क नहीं पड़ता कि आप वास्तव में मूल्य का उपयोग करते हैं। –

+0

डरावना अध्ययन मैं इस तरह के बयान का मूल्यांकन करने की आदत रखता था। क्या कोई यह जांचता है कि यह ($ और) खराब अभ्यास कितना बुरा है? 10%/30% तक और परिणाम साझा कर सकते हैं? –

14

मैं इस पसंद करते हैं:

my ($table_name) = $line =~ m/(\S{2}DT\S{3})/i; 

यह

  1. स्कैन $line और कब्जा पाठ पैटर्न के लिए इसी
  2. रिटर्न "सभी" कैप्चर (1) "सूची" के लिए दूसरी तरफ।

यह psuedo-list संदर्भ यह है कि हम किसी सूची में पहली आइटम को कैसे पकड़ते हैं। ऐसा वही किया जाता है जैसे पैरामीटर एक सबराउटिन में पास हो जाते हैं।

my ($first, $second, @rest) = @_; 


my ($first_capture, $second_capture, @others) = $feldman =~ /$some_pattern/; 

नोट:: यह कहा, अपने regex स्थितियों के एक मुट्ठी भर से ज्यादा पाठ के बारे में बहुत ज्यादा में उपयोगी होने के लिए मान लिया गया है। कोई तालिका नाम कैप्चर नहीं कर रहा है जिसमें 7 में से 3 और 4 पदों के रूप में डीटी नहीं है? यह 1) त्वरित और गंदे के लिए पर्याप्त है, 2) यदि आप सीमित प्रयोज्यता के साथ ठीक हैं।

+0

में प्रभाव को कम करते हैं, यह वास्तव में सूची संदर्भ है, इसके बारे में कुछ भी छद्म नहीं है! मुश्किल चीज एक आइटम की सूची का उपयोग कर रही है। एक आइटम सूची में किसी ऑपरेशन के परिणामों को कैप्चर करना बहुत आसान हो सकता है जब आप ऑपरेटर या सबराउटिन से सूची-संदर्भ व्यवहार को मजबूर करना चाहते हैं। 'मेरा $ foo = @bar;' 'my ($ foo) = @bar; 'से बहुत अलग है, और भेद बहुत आसान हो सकता है। – daotoad

+0

ओह, यह आसान में आता है। मैं इसका हर समय उपयोग करता हूं।मुझे लगता है कि "छद्म" इसे रखने का एक बुरा तरीका है। मुझे पता है कि एक की सूची अभी भी एक सूची है, यह सिर्फ एक स्केलर की तरह एक भयानक लग रहा है - और यह सब मैं वैसे भी पाने की कोशिश कर रहा हूं। – Axeman

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

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