2010-05-10 12 views
8

मैं पर्ल में एक विशेष रूप से विशेष खोज इंजन कार्यान्वयन पर काम कर रहा हूं, यह विशेष रूप से सीमित (पेंट: का उप-समूह) के लिए दस्तावेजों (रेगेक्स) दस्तावेजों की खोज करता है:) एक पाठ फ़ाइल से तार। मैं सामान्य सर्च इंजन इंडेक्सिंग चाल कर रहा हूं, लेकिन एक समस्या है।मैं नियमित अभिव्यक्ति के 0 टोकन "(गलत शब्द) की पहचान कैसे कर सकता हूं

कुछ खोज रेगेक्स पैटर्न में, फ़ाइल में उपयोग किए जाने वाले डिलीमीटरों की आवश्यकता होती है। "ठीक है, मैं खुद से सोचता हूं," शब्द निकटता, फिर ... आसान "... और समीकरण का वह पक्ष सीधे आगे है।

चाल यह है कि खोज पैटर्न नियमित अभिव्यक्ति होते हैं, मैं हेवन । 'टी आसानी से विशिष्ट शब्द है कि मैं अनुक्रमित डेटा में की तलाश में जाना चाहिए (लगता है कि "विभाजन" अगर हम अधिक साधारण तार के बारे में बात कर रहे हैं)

तुच्छ उदाहरण निर्धारित किया है, "वर्ग [\ s -] * नृत्य" सीधे "स्क्वायरेंस" पर मिलेंगे लेकिन "स्क्वायर डांस" और "स्क्वायर-डांस" पर एक निकटता मैच (क्योंकि '-' एक डिलीमीटर है)। मुझे "वर्ग" और " नृत्य "अलग से, लेकिन एक दूसरे के नजदीक।

मैं challe के लिए खेल हूँ nge, लेकिन मैं बजाय स्थापित कोड का उपयोग करना होगा। मेरा आंत मुझे बताता है कि यह रेगेक्स इंजन के लिए एक आंतरिक हुक होगा, लेकिन मुझे ऐसा कुछ भी पता नहीं है। कोई सुझाव?

+0

क्या खोज पैटर्न मनमाने ढंग से जटिल हो सकते हैं? यदि आप एक इंडेक्स बनाने के लिए समय ले रहे हैं, तो अपने स्टोरेज प्रारूप को डीकोड क्यों न करें और जिन बिट्स की आप परवाह है उन्हें खोजें? –

उत्तर

4

re pragma जानकारी उत्पादन कर सकते हैं आप में रुचि होने लगते हैं

use strict; 
use warnings; 
use re qw(Debug DUMP); 

my $re = qr/square[\s-]*dance/; 

'Let\'s go to the square dance!' =~ $re; 

आउटपुट:।

Compiling REx "square[\s-]*dance" 
Final program: 
    1: EXACT <square> (4) 
    4: STAR (17) 
    5: ANYOF[\11\12\14\15 \-][+utf8::IsSpacePerl] (0) 
    17: EXACT <dance> (20) 
    20: END (0) 
anchored "square" at 0 floating "dance" at 6..2147483647 (checking anchored) minlen 11 
Freeing REx: "square[\s-]*dance" 

दुर्भाग्य से, वहाँ यह जानकारी प्राप्त करने के लिए एक कार्यक्रम संबंधी हुक होने के लिए प्रकट नहीं होता है । आपको एसटीडीईआरआर पर आउटपुट को रोकना होगा और इसे पार्स करना होगा। रफ-का-प्रमाण अवधारणा:

sub build_regexp { 
    my $string = shift; 
    my $dump; 

    # save off STDERR and redirect to scalar 
    open my $stderr, '>&', STDERR or die "Can't dup STDERR"; 
    close STDERR; 
    open STDERR, '>', \$dump or die; 

    # Compile regexp, capturing DUMP output in $dump 
    my $re = do { 
     use re qw(Debug DUMP); 
     qr/$string/; 
    }; 

    # Restore STDERR 
    close STDERR; 
    open STDERR, '>&', $stderr or die "Can't restore STDERR"; 

    # Parse DUMP output 
    my @atoms = grep { /EXACT/ } split("\n", $dump); 

    return $re, @atoms; 
} 

इसे इस तरह का उपयोग करें:

my ($re, @atoms) = build_regexp('square[\s-]*dance'); 

$re पैटर्न होता है, @atoms पैटर्न का शाब्दिक भागों की सूचियों में शामिल है। इस मामले में, यह

1: EXACT <square> (4) 
    17: EXACT <dance> (20) 
+0

डेटा प्राप्त करने के लिए एसटीडीईआरआर को पुनर्निर्देशित करने की आवश्यकता के बारे में बहुत बुरा है, लेकिन यह एक शानदार समाधान है। धन्यवाद! – Trueblood

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