2012-05-16 7 views
6

मान लें कि मैं अक्षरों के बीच की दूरी के साथ "कुत्तों" शब्द को एक बड़े (300,000 अक्षरों) में ढूंढना चाहता हूं, ठीक बीच में 40,000 अक्षर। तो मुझे क्या करना:पर्ल: "रेगेक्स में 32766 से बड़ा {0} में क्वांटिफायर"

$mystring =~ m/d.{40000}o.{40000}g.{40000}s/; 

यह अन्य (धीमा) भाषाओं में काफी अच्छी तरह से काम करेगा, लेकिन पर्ल में यह मेरे "में {} regex में 32766 से भी बड़ा परिमाणक" फेंकता है।

तो:

  1. तक हम बड़ी संख्या परिमाणक किसी भी तरह के रूप में उपयोग कर सकते हैं?
  2. यदि नहीं, तो क्या मुझे यह जानने का एक और अच्छा तरीका है? ध्यान दें कि "कुत्तों" केवल एक उदाहरण है; मैं इसे किसी भी शब्द और किसी भी कूद आकार (और तेज़) के लिए करना चाहता हूं।

उत्तर

9

तुम सच में ऐसा करने की जरूरत है इस तेजी मैं Boyer-Moore string search के विचारों पर आधारित एक कस्टम खोज पर विचार करेंगे। एक नियमित अभिव्यक्ति को एक सीमित राज्य मशीन में पार्स किया जाता है। यहां तक ​​कि एक एफएसएम का एक चालाक, कॉम्पैक्ट प्रतिनिधित्व आपके द्वारा वर्णित खोज निष्पादित करने का एक बहुत ही प्रभावी तरीका नहीं होगा।

यदि आप वाकई लाइनों के साथ जारी रखना चाहते हैं तो आप अब .{30000}.{10000} जैसे दो अभिव्यक्तियों को जोड़ सकते हैं जो अभ्यास में .{40000} जैसा ही है।

+0

अच्छा काम के आसपास। मैंने स्क्रैच से कुछ लिखने पर विचार किया, लेकिन यह मेरे लिए थोड़ा अधिक है क्योंकि प्रैक्टिस में मैं ब्रूट-फोर्स रेगेक्स विधि में चलने वाली खोजों में केवल दस मिनट या तो मेरे उपयोग के लिए स्वीकार्य होगा। –

+0

@GadiA मैं उत्सुक होगा यदि 'अध्ययन' किसी भी मैच के प्रदर्शन में सुधार करेगा। –

5

मुझे लगता है कि index इस कार्य के लिए बेहतर अनुकूल हो सकता है। पूरी तरह से अपरीक्षित की तर्ज पर कुछ:

sub has_dogs { 
    my $str = shift; 
    my $start = 0 

    while (-1 < (my $pos = index $$str, 'd', $start)) { 
     no warnings 'uninitialized'; 
     if (('o' eq substr($$str, $pos + 40_000, 1)) and 
      ('g' eq substr($$str, $pos + 80_000, 1)) and 
      ('s' eq substr($$str, $pos + 120_000, 1))) { 
      return 1; 
     } 
    } 
    return; 
} 
5

40.000 = 2 * 20.000

/d(?:.{20000}){2}o(?:.{20000}){2}g(?:.{20000}){2}s/s 
+0

उपरोक्त यांत्रिक रूप से करना आसान है, इसलिए यह "किसी भी आकार" के लिए आपके अनुरोध को पूरा करता है। दूसरा, आप वास्तव में "एस" का उपयोग करना चाहते हैं, अन्यथा /'.'/ साधन/'[^ \ n]'/* अनिवार्य जांच के * बहुत * होंगे। – ikegami

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