2010-07-14 10 views
7

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

यह वर्तमान में regex मैं

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)/80 })"$2>$3<\/textarea>/gis; 

उपयोग कर रहा हूँ दुर्भाग्य से पर्ल पहचानने जा करने के लिए क्या मुझे बताया गया था अंदर पर्ल कोड एम्बेड करने के लिए वाक्य रचना था प्रतीत नहीं होता खोज एवं प्रतिस्थापन regexs रहे है वहाँ कोई पर्ल junkies मुझे यह बताने के लिए तैयार है कि मैं क्या गलत कर रहा हूँ? सादर, ज़ैक

उत्तर

11

(?{...}) पैटर्न मिलान पक्ष पर कोड निष्पादित करने के लिए एक प्रयोगात्मक सुविधा है, लेकिन आप कोड को निष्पादित करना चाहते हैं प्रतिस्थापन पक्ष। उस के लिए /e नियमित अभिव्यक्ति स्विच का उपयोग करें:

#! /usr/bin/perl 

use warnings; 
use strict; 

use POSIX qw/ ceil /; 

while (<DATA>) { 
    s[<textarea rows="(.+?)"(.*?)>(.*?)</textarea>] { 
    my $rows = ceil(length($3)/80); 
    qq[<textarea rows="$rows"$2>$3</textarea>]; 
    }egis; 
    print; 
} 

__DATA__ 
<textarea rows="123" bar="baz">howdy</textarea> 

आउटपुट:

<textarea rows="1" bar="baz">howdy</textarea>
0

मेरा मानना ​​है कि आपकी समस्या को कोई अनपेक्षित /

है यदि यह समस्या नहीं है, यह निश्चित रूप से एक समस्या है।

ऐसा करें, ध्यान दें \/80

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)\/80 })"$2>$3<\/textarea>/gis; 

इस कोड के लिए बुनियादी पैटर्न है:

$file =~ s/some_search/some_replace/gis; 

gis विकल्प है, जो मैं को देखने के लिए होगा रहे हैं। मुझे लगता है कि जी = ग्लोबल, i = केस असंवेदनशील, एस = अभी कुछ भी दिमाग में नहीं आता है।

+0

एक पर्ल जंकी, मैं नहीं हूँ। हालांकि, मुझे लगा कि मैं इस पर काम करूंगा। –

1

यह रेगेक्स के साथ किया जाना चाहिए? रेगेक्स के साथ किसी भी मार्कअप भाषा (या यहां तक ​​कि सीएसवी) को पार्स करना त्रुटि से भरा हुआ है। आप एक मानक पुस्तकालय का उपयोग करने की कोशिश कर सकते हैं:

http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html

(हाँ, लेख कुछ सरल स्ट्रिंग-हेरफेर के लिए कमरे में छोड़ देता है:

http://search.cpan.org/dist/HTML-Parser/Parser.pm

नहीं तो आप Cthulu का बदला जोखिम , इसलिए मुझे लगता है कि आपकी आत्मा सुरक्षित है, हालांकि :-)

5

वाक्य रचना आप कोड एम्बेड करने के लिए प्रयोग कर रहे हैं प्रतिस्थापन की "मैच" भाग (बाएं हाथ में ही मान्य है की ओर)। दाहिने हाथ की ओर में कोड एम्बेड करने के लिए (जो एक सामान्य पर्ल डबल उद्धृत स्ट्रिंग है), तो आप ऐसा कर सकते हैं:

$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>} 
      {<textarea rows="@{[ length($3)/80 ]}"$2>$3</textarea>}gis; 

यह "some string @{[ embedded_perl_code() ]} more string" के पर्ल मुहावरा उपयोग करता है।

लेकिन अगर आप एक बहुत जटिल बयान के साथ काम कर रहे हैं, यह "eval" मोड, जहां यह पर्ल कोड के रूप में बदलने स्ट्रिंग व्यवहार करता है में प्रतिस्थापन डाल करने के लिए आसान हो सकता है:

$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>} 
      {'<textarea rows="' . (length($3)/80) . qq{"$2>$3</textarea>}}gise; 

नोट दोनों में है कि उदाहरण रेगेक्स को s{}{} के रूप में संरचित किया गया है। यह न केवल स्लेश से बचने की आवश्यकता को समाप्त करता है, बल्कि आपको पठनीयता के लिए कई पंक्तियों पर अभिव्यक्ति फैलाने की अनुमति देता है।

0

सबसे पहले, आपको प्रतिस्थापन पाठ में अभिव्यक्ति के अंदर / उद्धृत करने की आवश्यकता है (अन्यथा perl एक s /// ऑपरेटर को 80 और उसके बाद संख्या के बाद देखेंगे)। या आप एक अलग डेलीमीटर का उपयोग कर सकते हैं; जटिल प्रतिस्थापन के लिए, मिलान ब्रैकेट एक अच्छा विचार है।

फिर आप मुख्य समस्या प्राप्त करते हैं, जो कि (?{...}) केवल पैटर्न में उपलब्ध है। प्रतिस्थापन पाठ एक पैटर्न नहीं है, यह (लगभग) एक साधारण स्ट्रिंग है।

इसके बजाय, s/// ऑपरेटर में संशोधक है, जो आपको प्रतिस्थापन स्ट्रिंग के बजाय प्रतिस्थापन अभिव्यक्ति लिखने देता है।

 
$file =~ s(<textarea rows="(.+?)"(.*?)>(.*?)</textarea>) 
      ("<textarea rows=\"" . (length($3)/80) . "\"$2>$3</textarea>")egis; 
0

प्रति http://perldoc.perl.org/perlrequick.html#Search-and-replace रूप में, यह "मूल्यांकन संशोधक s///e" के साथ पूरा किया जा सकता है, उदाहरण के लिए, आप gis एक अतिरिक्त e उस में होना आवश्यक है।

मूल्यांकन संशोधक एस /// ई प्रतिस्थापन स्ट्रिंग के आसपास एक eval {...} लपेटता है और मूल्यांकन परिणाम मिलान किए गए सबस्ट्रिंग के लिए प्रतिस्थापित किया जाता है। कुछ उदाहरण:

# convert percentage to decimal 
$x = "A 39% hit rate"; 
$x =~ s!(\d+)%!$1/100!e;  # $x contains "A 0.39 hit rate" 
संबंधित मुद्दे