2009-06-27 13 views
5

के साथ सादा पाठ से यूआरएल निकालने के लिए रेगेक्स का उपयोग करना मैं सादा पाठ से विशिष्ट एक्सटेंशन के साथ एक विशिष्ट डोमेन (संभवतः परिवर्तनीय सबडोमेन के साथ) के सभी यूआरएल निकालने के लिए पर्ल रेगेक्सप्स का उपयोग कैसे कर सकता हूं? मैंने कोशिश की है:पर्ल

my $stuff = 'omg http://fail-o-tron.com/bleh omg omg omg omg omg http://homepage.com/woot.gif dfgdfg http://shomepage.com/woot.gif aaa'; 
while($stuff =~ m/(http\:\/\/.*?homepage.com\/.*?\.gif)/gmsi) 
{ 
print $1."\n"; 
} 

यह बुरी तरह विफल रहता है और मुझे देता है:

http://fail-o-tron.com/bleh omg omg omg omg omg http://homepage.com/woot.gif 
http://shomepage.com/woot.gif 

मैंने सोचा था कि क्योंकि मैं .*? का उपयोग कर रहा है, जो चाहिए गैर लालची हो सकता है और मुझे सबसे छोटी देने के लिए नहीं होगा मैच। कोई मुझे बता सकता हैं मुझसे क्या गलती हो रही है? (मैं कुछ uber-जटिल, डिब्बाबंद regexp यूआरएल को मान्य नहीं करना चाहता, मैं पता है कि मैं गलत कर रहा हूँ तो मैं इसे से सीख सकते हैं चाहते हैं।)

उत्तर

5

जाएँ CPAN: Regexp::Common::URI

संपादित: यहां तक ​​कि यदि आप डिब्बाबंद नियमित अभिव्यक्ति नहीं चाहते हैं, तो यह आपको परीक्षण किए गए परीक्षण मॉड्यूल के स्रोत को देखने में मदद कर सकता है।

यदि आप किसी निश्चित स्ट्रिंग से मेल खाने वाले यूआरएल खोजना चाहते हैं, तो आप आसानी से इस मॉड्यूल का उपयोग करने के लिए इसका उपयोग कर सकते हैं।

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Regexp::Common qw/URI/; 

while (<>) { 
    if (m/$RE{URI}{HTTP}{-keep}/) { 
    print $_ if $1 =~ m/what-you-want/; 
    } 
} 
16

URI::Find विशेष रूप से इस समस्या को हल करने के लिए डिज़ाइन किया गया है। यह सभी यूआरआई पाएगा और फिर आप उन्हें फ़िल्टर कर सकते हैं। पीछे विराम चिह्न जैसी चीजों को संभालने के लिए इसमें कुछ ह्युरिस्टिक्स हैं।

अपडेट: हाल ही में यूनिकोड को संभालने के लिए अपडेट किया गया।

0

मैंने सोचा कि ऐसा नहीं होना चाहिए क्योंकि मैं उपयोग कर रहा हूं। *? जो गैर लालची हो सकता है और मुझे सबसे छोटी मैच

यह करता है देने के लिए चाहिए, लेकिन यह आप छोटी से छोटी मैच सही जा रहा देता है। पहले http से शुरू हो रहा है और सही हो रहा है, यह सबसे छोटा मैच है।

कृपया भविष्य के लिए ध्यान दें, आपको स्लेश से बचने की ज़रूरत नहीं है, क्योंकि आपको अपने विभाजक के रूप में स्लेश का उपयोग करने की आवश्यकता नहीं है। और आपको कोलन से बचने की ज़रूरत नहीं है। अगली बार सिर्फ इस कार्य करें:

m|(http://.*?homepage.com\/.*?\.gif)| 

या

m#(http://.*?homepage.com\/.*?\.gif)# 

या

m<(http://.*?homepage.com\/.*?\.gif)> 

या अन्य पात्रों के बहुत सारे में से एक, perlre दस्तावेज़ देखें।

1

यूआरएल को रिक्त स्थान रखने की अनुमति नहीं है, इसलिए इसके बजाय। *? आपको शून्य-या-अधिक गैर-स्पेस वर्णों के लिए \ S * ?, का उपयोग करना चाहिए। निकालने | | स्ट्रिंग से किए गए सभी URL प्राप्त |

+0

[RFC 3986 परिशिष्ट सी] (http://tools.ietf.org/html/rfc3986#appendix-C) यूआरआई निकालने की विशेष समस्याओं पर चर्चा करता है, जिसमें व्हाइटस्पेस स्वीकार्य होने पर मामलों सहित। "कुछ मामलों में, अतिरिक्त सफेद जगह (रिक्त स्थान, रेखा-ब्रेक, टैब इत्यादि) को लाइनों में लंबी यूआरआई तोड़ने के लिए जोड़ा जाना पड़ सकता है। जब यूआरआई निकाला जाता है तो व्हाइटस्पेस को अनदेखा किया जाना चाहिए।" और "मजबूती के लिए, उपयोगकर्ता द्वारा टाइप किए गए यूआरआई को स्वीकार करने वाले सॉफ़्टवेयर को दोनों डिलीमीटर और एम्बेडेड व्हाइटस्पेस को पहचानने और पट्टी करने का प्रयास करना चाहिए।" उस अनुभव से, यह मुश्किल है। – Schwern

0

यहाँ एक regex के लिए (उम्मीद) मिलता है पाठ फ़ाइल, ऐसा लगता है कि मेरे लिए काम किया जाना है:

m,(http.*?://([^\s)\"](?!ttp:))+),g 

...या एक उदाहरण में: - और "खाली स्थान के, " और ) का उपयोग करता

$ echo -e "\n\na blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah \"https://poi.com/a%20b\"; (http://bbb.comhttp://roch.com/abc) \n" | perl -dne 'use re "debug" ; while (my $string = <>) { print "$string\n"; while ($string =~ m,(http.*?://([^\s)\"](?!ttp:))+),g) {print "$&\n"} }' 

regex http(s):// पर मेल खाता है:

$ echo -e "\n\na blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah \"https://poi.com/a%20b\"; (http://bbb.comhttp://roch.com/abc) \n" | perl -ne 'while (my $string = <>) { print "$string\n"; while ($string =~ m,(http.*?://([^\s)\"](?!ttp:))+),g) {print "$&\n"} }' 


a blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah "https://poi.com/a%20b"; (http://bbb.comhttp://roch.com/abc) 

http://www.abc.com/dss.htm?a=1&p=2#chk 
https://poi.com/a%20b 
http://bbb.com 
http://roch.com/abc 

मेरी noob संदर्भ के लिए, ऊपर एक ही आदेश की डिबग संस्करण है बाहर निकलें "अक्षर; फिर positive lookahead का उपयोग प्रारंभ में, "http" पर "बाहर निकलने" का कारण होता है, शाब्दिक समूह (यदि कोई मिलान पहले से ही प्रगति पर है); हालांकि, चूंकि यह पिछले मैच के आखिरी चरित्र "खाता है", यहां लुकहेड मैच एक चरित्र को आगे बढ़ाकर "ttp:" में ले जाया गया है।

कुछ उपयोगी पृष्ठों:

आशा इस मदद करता है किसी को,
012,351,चीयर्स!

संपादित करें: अप, बस URI::Find::Simple - search.cpan.org के बारे में पाया, एक ही बात (के माध्यम से regex - Getting the website title from a link in a string)

2

मैं लिंक जो * .htm की तरह विशिष्ट एक्सटेंशन
साथ समाप्त होता है निकालने के लिए कोड निम्नलिखित का इस्तेमाल किया है करने के लिए लगता है * एचटीएमएल, * .gif, * .jpeg। नोट: इस स्क्रिप्ट एक्सटेंशन * .html में पहले और फिर * .htm लिखा गया है क्योंकि दोनों में "htm" सामान्य है। तो इस तरह के बदलाव ध्यान से किया जाना चाहिए।

इनपुट: फ़ाइल का नाम लिंक और आउटपुट फ़ाइल नाम है जहां परिणाम सहेजे जाएंगे।
आउटपुट: आउटपुट फ़ाइल में सहेजा जाएगा।

कोड यहाँ जाता है: अपने स्ट्रिंग के

use strict; 
use warnings; 

if ($#ARGV != 1) { 
print 
"Incorrect number of arguments.\nArguments: Text_LinkFile, Output_File\n"; 
die $!; 
} 
open FILE_LINKS, $ARGV[0] or die $!; 
open FILE_RESULT, ">$ARGV[1]" or die $!; 

my @Links; 
foreach (<FILE_LINKS>) { 
    my @tempArray; 
    my (@Matches) =($_ =~ m/((https?|ftp):\/\/[^\s]+\.(html?|gif|jpe?g))/g); 
    for (my $i = 0 ; $i < $#Matches ; $i += 3) { 
     push(@Links, $Matches[$i]); 
     } 
    } 
print FILE_RESULT join("\n", @Links); 

आउटपुट यहाँ है:

http://homepage.com/woot.gif 
http://shomepage.com/woot.gif 
+0

'(html | htm | gif | jpeg | jpg) 'के बजाय आप' (html? | Gif | jpe? G)' का उपयोग क्यों नहीं करते? –

+0

@ ब्रैड गिल्बर्ट: हाँ यह बेहतर है :) – Pushpendra

+0

बिल्कुल सही, सही! –

1
https?\:\/\/[^\s]+[\/\w] 

इस regex मेरे लिए काम किया

+0

थोड़ा और संदर्भ और/या स्पष्टीकरण अच्छा होगा। –